Skip to content

Luau C API Reference

State Manipulation

lua_newstate

lua_State* lua_newstate(lua_Alloc f, void* ud) [-0, +0, -]

  • f: Luau allocator function.
  • ud: Opaque userdata pointer that is passed to the allocator function.

Creates a new Luau state. If the allocator fails to allocate memory for the new state, this function will return nullptr. Use lua_close() to close the state once done.

The allocator function is used for all Luau memory allocations, including the initial construction of the state itself.

lua_State* L = lua_newstate(allocator, nullptr);
lua_close(L);
Allocator Example

This is functionally identical to the allocator function used by the luaL_newstate helper function.

static void* allocator(void* ud, void* ptr, size_t old_size, size_t new_size) {
    (void)ud; (void)old_size; // Not using these

    // new_size of 0 indicates the allocator should free the ptr
    if (new_size == 0) {
        free(ptr);
        return nullptr;
    }

    return realloc(ptr, new_size);
}

lua_State* L = lua_newstate(allocator, nullptr);


luaL_newstate

lua_State* luaL_newstate() [-0, +0, -]

A simplified version of lua_newstate that uses the default allocator, which uses the standard free and realloc memory functions.


lua_close

void lua_close() [-0, +0, -]

Closes the Luau state. Luau objects are garbage collected and any dynamic memory is freed.

Smart Pointer Example

In modern C++, smart pointers can help with memory management. Here is an example of using a smart pointer that wraps around a Luau state and automatically calls lua_close() when dereferenced.

std::unique_ptr<lua_State, void(*)(lua_State*)> state(luaL_newState(), lua_close);


lua_newthread

lua_State* lua_newthread(lua_State* L) [-0, +1, -]

  • L: Parent thread

Creates a new Luau thread.


lua_mainthread

lua_State* lua_mainthread(lua_State* L) [-0, +0, -]

  • L: Lua thread

Returns the main Lua state (e.g. the state created from lua_newstate()).


lua_resetthread

void lua_resetthread(lua_State* L) [-0, +0, -]

  • L: Lua thread

Resets the Lua thread.


lua_isthreadreset

int lua_isthreadreset(lua_State* L) [-0, +0, -]

  • L: Lua thread

Checks if the Lua thread is reset.


Basic Stack Manipulation

lua_absindex

int lua_absindex(lua_State* L, int idx) [-0, +0, -]

  • L: Lua thread
  • idx: Index

Gets the absolute stack index. For example, if idx is -2, and the stack has 5 items, this function will return 4.


lua_gettop

int lua_gettop(lua_State* L) [-0, +0, -]

  • L: Lua thread

Gets the index representing the top of the stack. This also represents the number of items on the stack, since the stack index starts at 1. A stack size of 0 indicates an empty stack.

A common use of lua_gettop() is to get the number of arguments in a function call.

int custom_fn(lua_State* L) {
    int n_args = lua_gettop(L);
    lua_pushfstring("there are %d arguments", n_args);
    return 1;
}

lua_settop

int lua_settop(lua_State* L, int idx) [-?, +?, -]

  • L: Lua thread
  • idx: Top stack index

Sets the top of the stack, essentially resizing it to the given index. If the new size is larger than the current size, the new elements in the stack will be filled with nil values. Setting the stack size to 0 will clear the stack entirely.

lua_settop(L, 0); // clear the stack

lua_pushvalue

void lua_pushvalue(lua_State* L, int idx) [-0, +1, -]

  • L: Lua thread
  • idx: Stack index

Pushes a copy of the value at index idx to the top of the stack.


lua_remove

void lua_remove(lua_State* L, int idx) [-1, +0, -]

  • L: Lua thread
  • idx: Stack index

Removes the value at the given stack index idx. All other values above the index are shifted down.

Example
lua_pushinteger(L, 10);
lua_pushboolean(L, true);
lua_pushliteral(L, "hello");

lua_remove(L, -2); // remove the 'true' value.

printf("%s\n", luaL_tostring(L, -2)); // 'hello'

lua_insert

void lua_insert(lua_State* L, int idx) [-1, +1, -]

  • L: Lua thread
  • idx: Stack index

Moves the top stack element into the given index, shifting other values up first to give space. The element right under the top stack element becomes the new top element.

Example
lua_pushboolean(L, true);
lua_pushinteger(L, 10);
lua_pushliteral(L, "hello");
lua_pushinteger(L, 20);

// Current stack order:
// [-4] true
// [-3] 10
// [-2] hello
// [-1] 20

// Move the top value (20) to index -3.
// The values below the top and above -3 are shifted up.
// e.g. the '10' and 'hello' are shifted up first.
lua_insert(L, -3);

// New stack order:
// [-4] true
// [-3] 20
// [-2] 10
// [-1] hello

lua_replace

void lua_replace(lua_State* L, int idx) [-1, +0, -]

  • L: Lua thread
  • idx: Stack index

Moves the top element over top of the idx stack index. The old value at idx is overwritten. The top element is popped.

Example
lua_pushboolean(L, true);
lua_pushinteger(L, 10);
lua_pushliteral(L, "hello");
lua_pushinteger(L, 20);

// Current stack order:
// [-4] true
// [-3] 10
// [-2] hello
// [-1] 20

// Move the top value (20) to index -3.
// The values below the top and above -3 are shifted up.
// e.g. the '10' and 'hello' are shifted up first.
lua_replace(L, -3);

// New stack order:
// [-3] true
// [-2] 20
// [-1] hello

lua_checkstack

int lua_checkstack(lua_State* L, int size) [-0, +0, m]

  • L: Lua thread
  • size: Desired stack size

Ensures the stack is large enough to hold size more elements. This will only grow the stack, not shrink it. Returns true if successful, or false if it fails (e.g. the max stack size exceeded).

Example
// Ensure there are at least 2 more slots on the stack:
if (lua_checkstack(L, 2)) {
    lua_pushinteger(L, 10);
    lua_pushinteger(L, 20);
}

lua_rawcheckstack

void lua_rawcheckstack(lua_State* L, int size) [-0, +0, m]

  • L: Lua thread
  • size: Desired stack size

Similar to lua_checkstack, except it bypasses the max stack limit.


lua_xmove

void lua_xmove(lua_State* from, lua_State* to, int n) [-?, +?, -]

  • from: Lua thread
  • to: Lua thread
  • n: Number of items to move

Moves the top n elements in the from stack to the top of the to stack. This pops n values from the from stack and pushes n values to the to stack.

Note: Both from and to states must share the same global state (e.g. the main state created with lua_newstate).

Example
// Assume we have lua_State* A and B, both starting with empty stacks.

// Add some items to 'A' stack:
lua_pushboolean(A, true);
lua_pushinteger(A, 10);
lua_pushliteral(A, "hello");

// Moves the top 2 values from 'A' to 'B' (e.g. '10' and 'hello')
lua_xmove(A, B, 2);

printf("%d\n", lua_gettop(A)); // 1 (just the 'true' value remains)
printf("%d\n", lua_gettop(B)); // 2 (the '10' and 'hello' values)

lua_xpush

void lua_xpush(lua_State* from, lua_State* to, int idx) [-0, +1, -]

  • from: Lua thread
  • to: Lua thread
  • idx: Stack index

Pushes a value from the from state to the to state. The value at index idx in from is pushed to the top of the to stack. This is similar to lua_pushvalue, except the value is pushed to a different state.

Similar to lua_xmove, both from and to must share the same global state.

Example
// Push the value at index -2 within 'from' to the top of the 'to' stack:
lua_xpush(from, to, -2);

Access Functions

lua_isnumber

int lua_isnumber(lua_State* L, int idx) [-0, +0, -]

  • L: Lua thread
  • idx: Stack index

Returns 1 if the value at stack index idx is a number or the value is a string that can be coerced to a number. Otherwise, returns 0.


lua_isstring

int lua_isstring(lua_State* L, int idx) [-0, +0, -]

  • L: Lua thread
  • idx: Stack index

Returns 1 if the value at the given stack index is a string or a number (all numbers can be converted to a string). Otherwise, returns 0.


lua_iscfunction

int lua_iscfunction(lua_State* L, int idx) [-0, +0, -]

  • L: Lua thread
  • idx: Stack index

Returns 1 if the value at the given stack index is a C function. Otherwise, returns 0.


lua_isLfunction

int lua_isLfunction(lua_State* L, int idx) [-0, +0, -]

  • L: Lua thread
  • idx: Stack index

Returns 1 if the value at the given stack index is a Luau function. Otherwise, returns 0.


lua_isuserdata

int lua_isuserdata(lua_State* L, int idx) [-0, +0, -]

  • L: Lua thread
  • idx: Stack index

Returns 1 if the value at the given stack index is a userdata object. Otherwise, returns 0.


lua_type

int lua_type(lua_State* L, int idx) [-0, +0, -]

  • L: Lua thread
  • idx: Stack index

Returns the value type at the given stack index. If the stack index is invalid, this function returns LUA_TNONE.

List of lua types:

  • LUA_TNIL
  • LUA_TBOOLEAN
  • LUA_TLIGHTUSERDATA
  • LUA_TNUMBER
  • LUA_TVECTOR
  • LUA_TSTRING
  • LUA_TTABLE
  • LUA_TFUNCTION
  • LUA_TUSERDATA
  • LUA_TTHREAD
  • LUA_TBUFFER

lua_typename

const char* lua_typename(lua_State* L, int tp) [-0, +0, -]

  • L: Lua thread
  • tp: Luau type

Returns the name of the given type.

Example
const char* thread_name = lua_type(L, LUA_TTHREAD);
printf("%s\n", thread_name); // > "thread"

lua_equal

int lua_equal(lua_State* L, int idx1, int idx2) [-0, +0, -]

  • L: Lua thread
  • idx1: Stack index
  • idx2: Stack index

Returns 1 if the values at idx1 and idx2 are equal. If applicable, this will call the __eq metatable function. Use lua_rawequal to avoid the metatable call. Returns 0 if the values are not equal (including if either of the indices are invalid).

Example
lua_pushliteral(L, "hello");
lua_pushliteral(L, "hello");

if (lua_equal(L, -2, -1)) {
    printf("equal\n");
}

lua_rawequal

int lua_rawequal(lua_State* L, int idx1, int idx2) [-0, +0, -]

  • L: Lua thread
  • idx1: Stack index
  • idx2: Stack index

The same as lua_equal, except it does not call any metatable __eq functions.


lua_lessthan

int lua_lessthan(lua_State* L, int idx1, int idx2) [-0, +0, -]

  • L: Lua thread
  • idx1: Stack index
  • idx2: Stack index

Returns 1 if the value at idx is less than the value at idx2. Otherwise, returns 0. This may call the __lt metamethod function. Also returns 0 if either index is invalid.