Merge branch 'master' of git://factorcode.org/git/factor
[factor/jcg.git] / core / alien / alien-docs.factor
blobedac8c09cc6a46dfefbfbb18e6487d751d690688
1 USING: byte-arrays arrays help.syntax help.markup
2 alien.syntax compiler definitions math libc
3 debugger parser io io.backend system
4 alien.accessors eval ;
5 IN: alien
7 HELP: alien
8 { $class-description "The class of alien pointers. See " { $link "syntax-aliens" } " for syntax and " { $link "c-data" } " for general information." } ;
10 HELP: dll
11 { $class-description "The class of native library handles. See " { $link "syntax-aliens" } " for syntax and " { $link "dll.private" } " for general information." } ;
13 HELP: dll-valid? ( dll -- ? )
14 { $values { "dll" dll } { "?" "a boolean" } }
15 { $description "Returns true if the library exists and is loaded." } ;
17 HELP: expired?
18 { $values { "c-ptr" c-ptr } { "?" "a boolean" } }
19 { $description "Tests if the alien is a relic from an earlier session. A byte array is never considered to have expired, whereas passing " { $link f } " always yields true." } ;
21 HELP: <bad-alien>
22 { $values  { "alien" c-ptr } }
23 { $description "Constructs an invalid alien pointer that has expired." } ;
25 HELP: <library>
26 { $values
27      { "path" "a pathname string" } { "abi" "the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
28      { "library" library } }
29 { $description "Opens a C library using the path and ABI parameters and outputs a library tuple." }
30 { $notes "User code should use " { $link add-library } " so that the opened library is added to a global hashtable, " { $link libraries } "." } ;
32 HELP: libraries
33 { $description "A global hashtable that keeps a list of open libraries. Use the " { $link add-library } " word to construct a library and add it with a single call." } ;
35 HELP: <displaced-alien> ( displacement c-ptr -- alien )
36 { $values { "displacement" "an integer" } { "c-ptr" c-ptr } { "alien" "a new alien" } }
37 { $description "Creates a new alien address object, wrapping a raw memory address. The alien points to a location in memory which is offset by " { $snippet "displacement" } " from the address of " { $snippet "c-ptr" } "." }
38 { $notes "Passing a value of " { $link f } " for " { $snippet "c-ptr" } " creates an alien with an absolute address; this is how " { $link <alien> } " is implemented."
39 $nl
40 "Passing a zero absolute address does not construct a new alien object, but instead makes the word output " { $link f } "." } ;
42 { <alien> <displaced-alien> alien-address } related-words
44 HELP: alien-address ( c-ptr -- addr )
45 { $values { "c-ptr" c-ptr } { "addr" "a non-negative integer" } }
46 { $description "Outputs the address of an alien." }
47 { $notes "Taking the address of a " { $link byte-array } " is explicitly prohibited since byte arrays can be moved by the garbage collector between the time the address is taken, and when it is accessed. If you need to pass pointers to C functions which will persist across alien calls, you must allocate unmanaged memory instead. See " { $link "malloc" } "." } ;
49 HELP: <alien>
50 { $values { "address" "a non-negative integer" } { "alien" "a new alien address" } }
51 { $description "Creates an alien object, wrapping a raw memory address." }
52 { $notes "Alien objects are invalidated between image saves and loads." } ;
54 HELP: c-ptr
55 { $class-description "Class of objects consisting of aliens, byte arrays and " { $link f } ". These objects can convert to pointer C types, which are all aliases of " { $snippet "void*" } "." } ;
57 HELP: library
58 { $values { "name" "a string" } { "library" "a hashtable" } }
59 { $description "Looks up a library by its logical name. The library object is a hashtable with the following keys:"
60     { $list
61         { { $snippet "name" } " - the full path of the C library binary" }
62         { { $snippet "abi" } " - the ABI used by the library, either " { $snippet "cdecl" } " or " { $snippet "stdcall" } }
63         { { $snippet "dll" } " - an instance of the " { $link dll } " class; only set if the library is loaded" }
64     }
65 } ;
67 HELP: dlopen ( path -- dll )
68 { $values { "path" "a pathname string" } { "dll" "a DLL handle" } }
69 { $description "Opens a native library and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } "." }
70 { $errors "Throws an error if the library could not be found, or if loading fails for some other reason." }
71 { $notes "This is the low-level facility used to implement " { $link load-library } ". Use the latter instead." } ;
73 HELP: dlsym ( name dll -- alien )
74 { $values { "name" "a C symbol name" } { "dll" "a DLL handle" } { "alien" "an alien pointer" } }
75 { $description "Looks up a symbol in a native library. If " { $snippet "dll" } " is " { $link f } " looks for the symbol in the runtime executable." }
76 { $errors "Throws an error if the symbol could not be found." } ;
78 HELP: dlclose ( dll -- )
79 { $values { "dll" "a DLL handle" } }
80 { $description "Closes a DLL handle created by " { $link dlopen } ". This word might not be implemented on all platforms." } ;
82 HELP: load-library
83 { $values { "name" "a string" } { "dll" "a DLL handle" } }
84 { $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
86 HELP: add-library
87 { $values { "name" "a string" } { "path" "a string" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
88 { $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } "and the specified ABI." }
89 { $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " cannot be used in the same file as " { $link POSTPONE: FUNCTION: } " definitions from that library. The " { $link add-library } " call will happen too late, after compilation, and the alien calls will not work."
90 $nl
91 "Instead, " { $link add-library } " calls must either be placed in different source files from those that use that library, or alternatively, " { $link "syntax-immediate" } " can be used to load the library before compilation." }
92 { $examples "Here is a typical usage of " { $link add-library } ":"
93 { $code
94     "<< \"freetype\" {"
95     "    { [ os macosx? ] [ \"libfreetype.6.dylib\" \"cdecl\" add-library ] }"
96     "    { [ os windows? ] [ \"freetype6.dll\" \"cdecl\" add-library ] }"
97     "    [ drop ]"
98     "} cond >>"
100 "Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
102 HELP: alien-invoke-error
103 { $error-description "Thrown if the word calling " { $link alien-invoke } " was not compiled with the optimizing compiler. This may be a result of one of several failure conditions:"
104     { $list
105         { "This can happen when experimenting with " { $link alien-invoke } " in this listener. To fix the problem, place the " { $link alien-invoke } " call in a word; word definitions are automatically compiled with the optimizing compiler." }
106         { "The return type or parameter list references an unknown C type." }
107         { "The symbol or library could not be found." }
108         { "One of the four inputs to " { $link alien-invoke } " is not a literal value. To call functions which are not known at compile-time, use " { $link alien-indirect } "." }
109     }
110 } ;
112 HELP: alien-invoke
113 { $values { "..." "zero or more objects passed to the C function" } { "return" "a C return type" } { "library" "a logical library name" } { "function" "a C function name" } { "parameters" "a sequence of C parameter types" } }
114 { $description "Calls a C library function with the given name. Input parameters are taken from the data stack, and the return value is pushed on the data stack after the function returns. A return type of " { $snippet "\"void\"" } " indicates that no value is to be expected." }
115 { $notes "C type names are documented in " { $link "c-types-specs" } "." }
116 { $errors "Throws an " { $link alien-invoke-error } " if the word calling " { $link alien-invoke } " was not compiled with the optimizing compiler." } ;
118 HELP: alien-indirect-error
119 { $error-description "Thrown if the word calling " { $link alien-indirect } " was not compiled with the optimizing compiler. This may be a result of one of several failure conditions:"
120     { $list
121         { "This can happen when experimenting with " { $link alien-indirect } " in this listener. To fix the problem, place the " { $link alien-indirect } " call in a word; word definitions are automatically compiled with the optimizing compiler." }
122         { "The return type or parameter list references an unknown C type." }
123         { "One of the three inputs to " { $link alien-indirect } " is not a literal value." }
124     }
125 } ;
127 HELP: alien-indirect
128 { $values { "..." "zero or more objects passed to the C function" } { "funcptr" "a C function pointer" } { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
129 { $description
130     "Invokes a C function pointer passed on the data stack. Input parameters are taken from the data stack following the function pointer, and the return value is pushed on the data stack after the function returns. A return type of " { $snippet "\"void\"" } " indicates that no value is to be expected."
132 { $notes "C type names are documented in " { $link "c-types-specs" } "." }
133 { $errors "Throws an " { $link alien-indirect-error } " if the word calling " { $link alien-indirect } " is not compiled." } ;
135 HELP: alien-callback-error
136 { $error-description "Thrown if the word calling " { $link alien-callback } " was not compiled with the optimizing compiler. This may be a result of one of several failure conditions:"
137     { $list
138         { "This can happen when experimenting with " { $link alien-callback } " in this listener. To fix the problem, place the " { $link alien-callback } " call in a word; word definitions are automatically compiled with the optimizing compiler." }
139         { "The return type or parameter list references an unknown C type." }
140         { "One of the four inputs to " { $link alien-callback } " is not a literal value." }
141     }
142 } ;
144 HELP: alien-callback
145 { $values { "return" "a C return type" } { "parameters" "a sequence of C parameter types" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } { "quot" "a quotation" } { "alien" alien } }
146 { $description
147     "Defines a callback from C to Factor which accepts the given set of parameters from the C caller, pushes them on the data stack, calls the quotation, and passes a return value back to the C caller. A return type of " { $snippet "\"void\"" } " indicates that no value is to be returned."
148     $nl
149     "When a compiled reference to this word is called, it pushes the callback's alien address on the data stack. This address can be passed to any C function expecting a C function pointer with the correct signature. The callback is actually generated when the word calling " { $link alien-callback } " is compiled."
150     $nl
151     "Callback quotations run with freshly-allocated stacks. This means the data stack contains the values passed by the C function, and nothing else. It also means that if the callback throws an error which is not caught, the Factor runtime will halt. See " { $link "errors" } " for error handling options."
153 { $notes "C type names are documented in " { $link "c-types-specs" } "." }
154 { $examples
155     "A simple example, showing a C function which returns the difference of two given integers:"
156     { $code
157         ": difference-callback ( -- alien )"
158         "    \"int\" { \"int\" \"int\" } \"cdecl\" [ - ] alien-callback ;"
159     }
161 { $errors "Throws an " { $link alien-callback-error } " if the word calling " { $link alien-callback } " is not compiled." } ;
163 { alien-invoke alien-indirect alien-callback } related-words
165 ARTICLE: "alien-expiry" "Alien expiry"
166 "When an image is loaded, any alien objects which persisted from the previous session are marked as having expired. This is because the C pointers they contain are almost certainly no longer valid."
168 "For this reason, the " { $link POSTPONE: ALIEN: } " word should not be used in source files, since loading the source file then saving the image will result in the literal becoming expired. Use " { $link <alien> } " instead, and ensure the word calling " { $link <alien> } " is not declared " { $link POSTPONE: flushable } "."
169 { $subsection expired? } ;
171 ARTICLE: "aliens" "Alien addresses"
172 "Instances of the " { $link alien } " class represent pointers to C data outside the Factor heap:"
173 { $subsection <alien> }
174 { $subsection <displaced-alien> }
175 { $subsection alien-address }
176 "Anywhere that a " { $link alien } " instance is accepted, the " { $link f } " singleton may be passed in to denote a null pointer."
178 "Usually alien objects do not have to created and dereferenced directly; instead declaring C function parameters and return values as having a pointer type such as " { $snippet "void*" } " takes care of the details."
179 { $subsection "syntax-aliens" }
180 { $subsection "alien-expiry" }
181 "When higher-level abstractions won't do:"
182 { $subsection "reading-writing-memory" }
183 { $see-also "c-data" "c-types-specs" } ;
185 ARTICLE: "reading-writing-memory" "Reading and writing memory directly"
186 "Numerical values can be read from memory addresses and converted to Factor objects using the various typed memory accessor words:"
187 { $subsection alien-signed-1 }
188 { $subsection alien-unsigned-1 }
189 { $subsection alien-signed-2 }
190 { $subsection alien-unsigned-2 }
191 { $subsection alien-signed-4 }
192 { $subsection alien-unsigned-4 }
193 { $subsection alien-signed-cell }
194 { $subsection alien-unsigned-cell }
195 { $subsection alien-signed-8 }
196 { $subsection alien-unsigned-8 }
197 { $subsection alien-float }
198 { $subsection alien-double }
199 "Factor numbers can also be converted to C values and stored to memory:"
200 { $subsection set-alien-signed-1 }
201 { $subsection set-alien-unsigned-1 }
202 { $subsection set-alien-signed-2 }
203 { $subsection set-alien-unsigned-2 }
204 { $subsection set-alien-signed-4 }
205 { $subsection set-alien-unsigned-4 }
206 { $subsection set-alien-signed-cell }
207 { $subsection set-alien-unsigned-cell }
208 { $subsection set-alien-signed-8 }
209 { $subsection set-alien-unsigned-8 }
210 { $subsection set-alien-float }
211 { $subsection set-alien-double } ;
213 ARTICLE: "loading-libs" "Loading native libraries"
214 "Before calling a C library, you must associate its path name on disk with a logical name which Factor uses to identify the library:"
215 { $subsection add-library }
216 "Once a library has been defined, you can try loading it to see if the path name is correct:"
217 { $subsection load-library } ;
219 ARTICLE: "alien-invoke" "Calling C from Factor"
220 "The easiest way to call into a C library is to define bindings using a pair of parsing words:"
221 { $subsection POSTPONE: LIBRARY: }
222 { $subsection POSTPONE: FUNCTION: }
223 "The above parsing words create word definitions which call a lower-level word; you can use it directly, too:"
224 { $subsection alien-invoke }
225 "Sometimes it is necessary to invoke a C function pointer, rather than a named C function:"
226 { $subsection alien-indirect }
227 "There are some details concerning the conversion of Factor objects to C values, and vice versa. See " { $link "c-data" } "." ;
229 ARTICLE: "alien-callback-gc" "Callbacks and code GC"
230 "A callback consits of two parts; the callback word, which pushes the address of the callback on the stack when executed, and the callback body itself. If the callback word is redefined, removed from the dictionary using " { $link forget } ", or recompiled, the callback body will not be reclaimed by the garbage collector, since potentially C code may be holding a reference to the callback body."
232 "This is the safest approach, however it can lead to code heap leaks when repeatedly reloading code which defines callbacks. If you are " { $emphasis "completely sure" } " that no running C code is holding a reference to any callbacks, you can blow them all away:"
233 { $code "USE: alien callbacks get clear-hash gc" }
234 "This will reclaim all callback bodies which are otherwise unreachable from the dictionary (that is, their associated callback words have since been redefined, recompiled or forgotten)." ;
236 ARTICLE: "alien-callback" "Calling Factor from C"
237 "Callbacks can be defined and passed to C code as function pointers; the C code can then invoke the callback and run Factor code:"
238 { $subsection alien-callback }
239 "There are some caveats concerning the conversion of Factor objects to C values, and vice versa. See " { $link "c-data" } "."
240 { $subsection "alien-callback-gc" }
241 { $see-also "byte-arrays-gc" } ;
243 ARTICLE: "dll.private" "DLL handles"
244 "DLL handles are a built-in class of objects which represent loaded native libraries. DLL handles are instances of the " { $link dll } " class, and have a literal syntax used for debugging prinouts; see " { $link "syntax-aliens" } "."
246 "Usually one never has to deal with DLL handles directly; the C library interface creates them as required. However if direct access to these operating system facilities is required, the following primitives can be used:"
247 { $subsection dlopen }
248 { $subsection dlsym }
249 { $subsection dlclose }
250 { $subsection dll-valid? } ;
252 ARTICLE: "embedding-api" "Factor embedding API"
253 "The Factor embedding API is defined in " { $snippet "vm/master.h" } "."
255 "The " { $snippet "F_CHAR" } " type is an alias for the character type used for path names by the operating system; " { $snippet "char" } " on Unix and " { $snippet "wchar_t" } " on Windows."
257 "Including this header file into a C compilation unit will declare the following functions:"
258 { $table
259     { {
260         { $code "void init_factor_from_args("
261             "    F_CHAR *image, int argc, F_CHAR **argv, bool embedded"
262             ")" }
263         "Initializes Factor."
264         $nl
265         "If " { $snippet "image" } " is " { $snippet "NULL" } ", Factor will load an image file whose name is obtained by suffixing the executable name with " { $snippet ".image" } "."
266         $nl
267         "The " { $snippet "argc" } " and " { $snippet "argv" } " parameters are interpreted just like normal command line arguments when running Factor stand-alone; see " { $link "cli" } "."
268         $nl
269         "The " { $snippet "embedded" } " flag ensures that this function returns as soon as Factor has been initialized. Otherwise, Factor will start up normally."
270     } }
271     { {
272         { $code "char *factor_eval_string(char *string)" }
273         "Evaluates a piece of code in the embedded Factor instance by passing the string to " { $link eval>string } " and returning the result. The result must be explicitly freed by a call to " { $snippet "factor_eval_free" } "."
274     } }
275     { {
276         { $code "void factor_eval_free(char *result)" }
277         "Frees a string returned by " { $snippet "factor_eval_string()" } "."
278     } }
279     { {
280         { $code "void factor_yield(void)" }
281         "Gives all Factor threads a chance to run."
282     } }
283     { {
284         { $code "void factor_sleep(long us)" }
285         "Gives all Factor threads a chance to run for " { $snippet "us" } " microseconds."
286     } }
287 } ;
289 ARTICLE: "embedding-restrictions" "Embedding API restrictions" 
290 "The Factor VM is not thread safe, and does not support multiple instances. There must only be one Factor instance per process, and this instance must be consistently accessed from the same thread for its entire lifetime. Once initialized, a Factor instance cannot be destroyed other than by exiting the process." ;
292 ARTICLE: "embedding-factor" "What embedding looks like from Factor"
293 "Factor code will run inside an embedded instance in the same way it would run in a stand-alone instance."
295 "One exception is that the global " { $link input-stream } " and " { $link output-stream } " streams are not bound by default, to avoid conflicting with any I/O the host process might perform. The " { $link init-stdio } " words must be called explicitly to initialize terminal streams."
297 "There is a word which can detect when Factor is embedded:"
298 { $subsection embedded? }
299 "No special support is provided for calling out from Factor into the owner process. The C library inteface works fine for this task - see " { $link "alien" } "." ;
301 ARTICLE: "embedding" "Embedding Factor into C applications"
302 "The Factor " { $snippet "Makefile" } " builds the Factor VM both as an executable and a library. The library can be used by other applications. File names for the library on various operating systems:"
303 { $table
304     { "OS" "Library name" "Shared?" }
305     { "Windows XP/Vista" { $snippet "factor.dll" } "Yes" }
306     ! { "Windows CE" { $snippet "factor-ce.dll" } "Yes" }
307     { "Mac OS X" { $snippet "libfactor.dylib" } "Yes" }
308     { "Other Unix" { $snippet "libfactor.a" } "No" }
310 "An image file must be supplied; a minimal image can be built, however the compiler must be included for the embedding API to work (see " { $link "bootstrap-cli-args" } ")."
311 { $subsection "embedding-api" }
312 { $subsection "embedding-factor" }
313 { $subsection "embedding-restrictions" } ;
315 ARTICLE: "alien" "C library interface"
316 "Factor can directly call C functions in native libraries. It is also possible to compile callbacks which run Factor code, and pass them to native libraries as function pointers."
318 "The C library interface is entirely self-contained; there is no C code which one must write in order to wrap a library."
320 "C library interface words are found in the " { $vocab-link "alien" } " vocabulary."
321 { $warning "C does not perform runtime type checking, automatic memory management or array bounds checks. Incorrect usage of C library functions can lead to crashes, data corruption, and security exploits." }
322 { $subsection "loading-libs" }
323 { $subsection "aliens" }
324 { $subsection "alien-invoke" }
325 { $subsection "alien-callback" }
326 { $subsection "c-data" }
327 { $subsection "dll.private" }
328 { $subsection "embedding" } ;
330 ABOUT: "alien"