package ocaml-lua

  1. Overview
  2. Docs

Module Lua_api_libSource

The Lua Application Program Interface (OCaml binding)

Difference with the original Lua API

Here is a list of functions of which you should read documentation:

Types definitions

Sourcetype state

See lua_State documentation.

Sourcetype oCamlFunction = state -> int

This type corresponds to lua_CFunction. See lua_CFunction documentation.

Sourcetype thread_status =
  1. | LUA_OK
  2. | LUA_YIELD
  3. | LUA_ERRRUN
  4. | LUA_ERRSYNTAX
  5. | LUA_ERRMEM
  6. | LUA_ERRERR
  7. | LUA_ERRFILE

See lua_status documentation.

Sourcetype gc_command =
  1. | GCSTOP
  2. | GCRESTART
  3. | GCCOLLECT
  4. | GCCOUNT
  5. | GCCOUNTB
  6. | GCSTEP
  7. | GCSETPAUSE
  8. | GCSETSTEPMUL

This type is not present in the official API and is used by the function gc

Sourcetype lua_type =
  1. | LUA_TNONE
  2. | LUA_TNIL
  3. | LUA_TBOOLEAN
  4. | LUA_TLIGHTUSERDATA
  5. | LUA_TNUMBER
  6. | LUA_TSTRING
  7. | LUA_TTABLE
  8. | LUA_TFUNCTION
  9. | LUA_TUSERDATA
  10. | LUA_TTHREAD

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_.

Sourcetype 'a lua_Reader = state -> 'a -> string option

See lua_Reader documentation.

Sourcetype writer_status =
  1. | NO_WRITING_ERROR
    (*

    No errors, go on writing

    *)
  2. | WRITING_ERROR
    (*

    An error occurred, stop writing

    *)
Sourcetype 'a lua_Writer = state -> string -> 'a -> writer_status

See lua_Writer documentation.

Constant values

Sourceval multret : int

Option for multiple returns in `Lua.pcall' and `Lua.call'. See lua_call documentation.

Sourceval registryindex : int

Pseudo-index to access the registry. See Registry documentation.

Sourceval environindex : int

Pseudo-index to access the environment of the running C function. See Registry documentation.

Sourceval globalsindex : int

Pseudo-index to access the thread environment (where global variables live). See Registry documentation.

Exceptions

Sourceexception Error of thread_status
Sourceexception Type_error of string

Functions not present in the Lua API

Sourceval thread_status_of_int : int -> thread_status

Convert an integer into a thread_status. Raises failure on invalid parameter.

Sourceval int_of_thread_status : thread_status -> int

Convert a thread_status into an integer.

Sourceval lua_type_of_int : int -> lua_type

Convert an integer into a lua_type. Raises failure on invalid parameter.

Sourceval int_of_lua_type : lua_type -> int

Convert a lua_type into an integer.

Lua API functions

See lua_atpanic documentation.

Sourceval call : state -> int -> int -> unit

See lua_call documentation.

Sourceval checkstack : state -> int -> bool

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.

Sourceval concat : state -> int -> unit

See lua_concat documentation.

Sourceval cpcall : state -> oCamlFunction -> 'a -> thread_status

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.

Sourceval createtable : state -> int -> int -> unit

See lua_createtable documentation.

Sourceval dump : state -> 'a lua_Writer -> 'a -> writer_status

See lua_dump documentation.

Sourceval equal : state -> int -> int -> bool

See lua_equal documentation.

Sourceval error : state -> 'a

See lua_error documentation.

Sourceval gc : state -> gc_command -> int -> int

See lua_gc documentation.

lua_getallocf not implemented in this binding

Sourceval getfenv : state -> int -> unit

See lua_getfenv documentation.

Sourceval getfield : state -> int -> string -> unit

See lua_getfield documentation.

Sourceval getglobal : state -> string -> unit

See lua_getglobal documentation. Like in the original Lua source code this function is implemented in OCaml using getfield.

Sourceval getmetatable : state -> int -> bool

See lua_getmetatable documentation.

Sourceval gettable : state -> int -> unit

See lua_gettable documentation.

Sourceval gettop : state -> int

See lua_gettop documentation.

Sourceval insert : state -> int -> unit

See lua_insert documentation.

Sourceval isboolean : state -> int -> bool

See lua_isboolean documentation.

Sourceval iscfunction : state -> int -> bool

See lua_iscfunction documentation.

Sourceval isfunction : state -> int -> bool

See lua_isfunction documentation.

Sourceval islightuserdata : state -> int -> bool

See lua_islightuserdata documentation.

Sourceval isnil : state -> int -> bool

See lua_isnil documentation.

Sourceval isnone : state -> int -> bool

See lua_isnone documentation.

Sourceval isnoneornil : state -> int -> bool

See lua_isnoneornil documentation.

Sourceval isnumber : state -> int -> bool

See lua_isnumber documentation.

Sourceval isstring : state -> int -> bool

See lua_isstring documentation.

Sourceval istable : state -> int -> bool

See lua_istable documentation.

Sourceval isthread : state -> int -> bool

See lua_isthread documentation.

Sourceval isuserdata : state -> int -> bool

See lua_isuserdata documentation.

Sourceval lessthan : state -> int -> int -> bool

See lua_lessthan documentation.

Sourceval load : state -> 'a lua_Reader -> 'a -> string -> thread_status

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.

Sourceval newtable : state -> unit

See lua_newtable documentation.

Sourceval newthread : state -> state

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.

Sourceval default_gc : state -> int

This is the default "__gc" function attached to any new userdatum created with newuserdata. See documentation of newuserdata below.

Sourceval make_gc_function : oCamlFunction -> oCamlFunction

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.

Sourceval newuserdata : state -> 'a -> unit

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!

Sourceval next : state -> int -> int

See lua_next documentation.

Sourceval objlen : state -> int -> int

See lua_objlen documentation.

Sourceval pcall : state -> int -> int -> int -> thread_status

See lua_pcall documentation.

Sourceval pop : state -> int -> unit

See lua_pop documentation.

Sourceval pushboolean : state -> bool -> unit

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

Sourceval pushcfunction : state -> oCamlFunction -> unit

See lua_pushcfunction documentation.

Sourceval pushocamlfunction : state -> oCamlFunction -> unit
Sourceval pushfstring : state -> ('a, unit, string, string) format4 -> 'a

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.

Sourceval pushinteger : state -> int -> unit

See lua_pushinteger documentation.

Sourceval pushlightuserdata : state -> 'a -> unit

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.

Sourceval pushliteral : state -> string -> unit

See lua_pushliteral documentation.

Sourceval pushlstring : state -> string -> unit

See lua_pushlstring documentation.

Sourceval pushnil : state -> unit

See lua_pushnil documentation.

Sourceval pushnumber : state -> float -> unit

See lua_pushnumber documentation.

Sourceval pushstring : state -> string -> unit

See lua_pushstring documentation.

Sourceval pushthread : state -> bool

See lua_pushthread documentation.

Sourceval pushvalue : state -> int -> unit

See lua_pushvalue documentation.

Sourceval pushvfstring : state -> ('a, unit, string, string) format4 -> 'a
Sourceval rawequal : state -> int -> int -> bool

See lua_rawequal documentation.

Sourceval rawget : state -> int -> unit

See lua_rawget documentation.

Sourceval rawgeti : state -> int -> int -> unit

See lua_rawgeti documentation.

Sourceval rawset : state -> int -> unit

See lua_rawset documentation.

Sourceval rawseti : state -> int -> int -> unit

See lua_rawseti documentation.

Sourceval register : state -> string -> oCamlFunction -> unit

See lua_register documentation. The function is implemented in OCaml using pushcfunction and setglobal.

Sourceval remove : state -> int -> unit

See lua_remove documentation.

Sourceval replace : state -> int -> unit

See lua_replace documentation.

Sourceval resume : state -> int -> thread_status

See lua_resume documentation.

lua_setallocf not implemented in this binding

Sourceval setfenv : state -> int -> bool

See lua_setfenv documentation.

Sourceval setfield : state -> int -> string -> unit

See lua_setfield documentation.

Sourceval setglobal : state -> string -> unit

See lua_setglobal documentation.

Sourceval setmetatable : state -> int -> int

See lua_setmetatable documentation.

Sourceval settable : state -> int -> unit

See lua_settable documentation.

Sourceval settop : state -> int -> unit

See lua_settop documentation.

Sourceval status : state -> thread_status

See lua_status documentation.

Sourceval toboolean : state -> int -> bool

See lua_toboolean documentation.

Sourceval tocfunction : state -> int -> oCamlFunction option

See lua_tocfunction documentation.

Sourceval toocamlfunction : state -> int -> oCamlFunction option
Sourceval tointeger : state -> int -> int

See lua_tointeger documentation.

Sourceval tolstring : state -> int -> string option

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

Sourceval tonumber : state -> int -> float

See lua_tonumber documentation.

The function lua_topointer is not available

Sourceval tostring : state -> int -> string option
Sourceval tothread : state -> int -> state option

See lua_tothread documentation.

Sourceval touserdata : state -> int -> [> `Userdata of 'a | `Light_userdata of 'a ] option

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!

Sourceval type_ : state -> int -> lua_type

See lua_type documentation.

Sourceval typename : state -> lua_type -> string

See lua_typename documentation.

Sourceval xmove : state -> state -> int -> unit

See lua_xmove documentation.

Sourceval yield : state -> int -> int

See lua_yield documentation.

OCaml

Innovation. Community. Security.