Page
Library
Module
Module type
Parameter
Class
Class type
Source
Lua_api_lib
SourceHere is a list of functions of which you should read documentation:
lua_close
, lua_getallocf
, lua_newstate
(see below here), lua_pushcclosure
(see below here), lua_setallocf
, lua_topointer
.newuserdata
, pushfstring
, pushlightuserdata
, touserdata
cpcall
, newthread
, default_gc
, make_gc_function
. tolstring
This type corresponds to lua_CFunction. See lua_CFunction documentation.
See lua_status documentation.
This type is not present in the official API and is used by the function gc
This type is a collection of the possible types of a Lua value, as defined by the macros in lua.h. As a reference, see the documentation of the lua_type function, and the corresponding OCaml Lua_api_lib.type_
.
See lua_Reader documentation.
See lua_Writer documentation.
Option for multiple returns in `Lua.pcall' and `Lua.call'. See lua_call documentation.
Pseudo-index to access the environment of the running C function. See Registry documentation.
Pseudo-index to access the thread environment (where global variables live). See Registry documentation.
Convert an integer into a thread_status
. Raises failure
on invalid parameter.
Convert a thread_status
into an integer.
Convert an integer into a lua_type
. Raises failure
on invalid parameter.
See lua_atpanic documentation.
See lua_checkstack documentation.
The function lua_close is not present because all the data structures of a Lua state are managed by the OCaml garbage collector.
See lua_concat documentation.
See lua_cpcall documentation.
NOTE: this function is not a binding of the original lua_cpcall, it's rather an OCaml function with the same semantics.
WARNING: the OCaml function you want to execute in a protected environment is actually protected againt Lua errors, even memory errors, but not against OCaml errors, i.e. exceptions. If for example you run:
let ls = LuaL.newstate ();;
let my_func ls = failwith "Sorry, my fault..."; 0;;
let cpcall_result = Lua.cpcall ls my_func 42;;
cpcall will actually raise a failure, because that exception is not generated by Lua but by OCaml.
See lua_createtable documentation.
See lua_dump documentation.
See lua_gc documentation.
lua_getallocf not implemented in this binding
See lua_getfenv documentation.
See lua_getfield documentation.
See lua_getglobal documentation. Like in the original Lua source code this function is implemented in OCaml using getfield
.
See lua_getmetatable documentation.
See lua_gettable documentation.
See lua_gettop documentation.
See lua_insert documentation.
See lua_isboolean documentation.
See lua_iscfunction documentation.
See lua_isfunction documentation.
See lua_islightuserdata documentation.
See lua_isnone documentation.
See lua_isnoneornil documentation.
See lua_isnumber documentation.
See lua_isstring documentation.
See lua_istable documentation.
See lua_isthread documentation.
See lua_isuserdata documentation.
See lua_lessthan documentation.
See lua_load documentation.
The function lua_newstate is not present because it makes very little sense to specify a custom allocator written in OCaml. To create a new Lua state, use the function Lua_aux_lib.newstate
.
See lua_newtable documentation.
See lua_newthread documentation.
When you create a new thread, this binding guaranties that the Lua object will remain "living" (protected from both the Lua and the OCaml garbage collectors) until a valid copy exists in at least one of the two contexts.
Remember that all the threads obtained by newthread
and Lua_api_lib.tothread
are shared copies, for example:
let state = LuaL.newstate ();;
let th = Lua.newthread state;;
let th' = match Lua.tothread state 1 with Some s -> s | None -> failwith "not an option!";;
Lua.settop state 0;;
Now the stack of state
is empty and you have two threads, th
and th'
, but they are actually the very same data structure and operations performed on the first will be visible on the second!
Another important issue regarding the scope of a state object representing a thread (coroutine): this binding don't prevent you from accessing invalid memory in case of misuse of the library. Please, carefully consider this fragment:
let f () =
let state = LuaL.newstate () in
let th = Lua.newthread state in
th;;
let th' = f ();;
Gc.compact ();; (* This will collect [state] inside [f] *)
(* Here something using [th'] *)
After Gc.compact
the value inside th'
has lost any possible meaning, because it's a thread (a coroutine) of a state object that has been already collected. Using th'
will lead to a segmentation fault, at best, and to an undefined behaviour if you are unlucky.
This is the default "__gc" function attached to any new userdatum created with newuserdata
. See documentation of newuserdata
below.
This function takes an oCamlFunction
you have created to be executed as "__gc" metamethod and "decorates" it with some default actions needed to deallocate all the memory.
If you want to create a "__gc" method for your userdata, you must register the value from make_gc_function
.
newuserdata
is the binding of lua_newuserdata but it works in a different way if compared to the original function, and the signature is slightly different.
In C lua_newuserdata
allocates an area for you, returns a void*
and you cast it as needed. Moreover, it pushes the new userdata on the stack.
In OCaml, however, you never allocates a value and so the resulting signature provides you a way to push an already created value on the top of the Lua stack.
Very important remark, read carefully. The original Lua lua_newuserdata
doesn't associate to the new userdatum any metatable, it's up to you to define a metatable with metamethods, if you need it. On the other hand, this binding silently creates a metatable with only one metamethod ("__gc") and associates the function default_gc
defined above. This function takes care of managing the memory between the two garbage collectors when needed. This is transparent to you, unless you want to attach to the userdatum a metatable of your, which is very likely to happen.
In case you want to attach a metatable to your userdatum you must include the "__gc" metamethod, and you must create the function using make_gc_function
described above.If you want a metatable for your userdatum but you don't need a "__gc", use in any case the default_gc
. Don't create a userdatum with a metatable and without "__gc" or your program will leak memory!
WARNING: using this function could be harmful because it actually breaks the type system. It has the same semantics of Obj.magic
, allowing the programmer to push an OCaml value into the Lua state, and then retrieve it with a different type. Be very careful!
See lua_objlen documentation.
See lua_pcall documentation.
See lua_pushboolean documentation.
The function lua_pushcclosure is not present because it makes very little sense to specify a "closure" written in OCaml, using the Lua upvalues machinery. Use instead Lua_api_lib.pushcfunction
See lua_pushcfunction documentation.
Alias of Lua_api_lib.pushcfunction
Pushes onto the stack a formatted string and returns the string itself. It is similar to the standard library function sprintf.
Warning: this function has a different behavior with respect to the original lua_pushfstring because the conversion specifiers are not restricted as specified in the Lua documentation, but you can use all the conversions of the Printf module.
See lua_pushinteger documentation.
See lua_pushlightuserdata documentation. Raises Not_a_block_value
if you try to push a non-block value (e.g. an immediate integer) as a light userdata.
In Lua a light userdata is a way to store inside the Lua state a C pointer. It's up the programmer to carefully check for the lifetime of the data structures passed to Lua via a light userdata. If you malloc a pointer and pass it to Lua, then you free it from C and then you retrieve the same pointer from Lua (using lua_touserdata), you are most probably shooting yourself in the foot.
To avoid this class of problems I decided to implement some logic in the binding of this function. When you push an OCaml value as a Lua light userdata, a global reference to that (OCaml) value is kept inside the Lua state L. So, if the original value goes out of scope it is not collected by the garbage collector. In this scenario:
let push_something state =
let ocaml_value = get_some_complex_value () in
pushlightuserdata state ocaml_value;
state
;;
when the push_something
function returns the Lua state, the ocaml_value
is not collected and can be retrieved at a later time from state
.
This behaviour has a major drawback: while ensuring the lifetime of objects, it wastes memory. All the OCaml values pushed as light userdata will in fact be collected when the garbage collector decide to collect the Lua state itself. This means that if you have a long running task (e.g. a server) with a Lua state and you use pushlightuserdata
, the values pushed will be never collected!
Moreover, if you push a value that have some resources associated with it (e.g. a channel, a socket or a DB handler) the resources will be released only when the Lua state goes out of scope.
See lua_pushliteral documentation.
See lua_pushlstring documentation.
See lua_pushnil documentation.
See lua_pushnumber documentation.
See lua_pushstring documentation.
See lua_pushthread documentation.
See lua_pushvalue documentation.
Alias of Lua_api_lib.pushfstring
See lua_rawequal documentation.
See lua_rawget documentation.
See lua_rawgeti documentation.
See lua_rawset documentation.
See lua_rawseti documentation.
See lua_register documentation. The function is implemented in OCaml using pushcfunction and setglobal.
See lua_remove documentation.
See lua_replace documentation.
See lua_resume documentation.
lua_setallocf not implemented in this binding
See lua_setfenv documentation.
See lua_setfield documentation.
See lua_setglobal documentation.
See lua_setmetatable documentation.
See lua_settable documentation.
See lua_settop documentation.
See lua_status documentation.
See lua_toboolean documentation.
See lua_tocfunction documentation.
Alias of Lua_api_lib.tocfunction
See lua_tointeger documentation.
See lua_tolstring documentation.
NOTE: The original len
argument is missing because, unlike in C, there is no impedance mismatch between OCaml and Lua strings
See lua_tonumber documentation.
The function lua_topointer is not available
Alias of Lua_api_lib.tolstring
See lua_tothread documentation.
If the value at the given acceptable index is a full userdata, returns its value as Some `Userdata v
. If the value is a light userdata, returns its value as Some `Light_userdata v
. Otherwise, returns None
.
WARNING: using this function could be harmful because it actually breaks the type system. It has the same semantics of Obj.magic
, allowing the programmer to push an OCaml value into the Lua state, and then retrieve it with a different type. Be very careful!
See lua_typename documentation.