# reflection

Responsible for lua-scripting execution and handling of API access cross-states.
You can use this to also contact other lua_State instances, and create new ones.
Do note you are responsible for spinning up new states.


# Functions

# reflection.is(name: string): boolean

reflection.is(name: string): boolean
  • checks if the current execution is of a named lua_State

# reflection.get(name: string): lua_State?

reflection.get(name: string): lua_State?
  • attempts to locate a lua_State

# reflection.current(): lua_State

reflection.current(): lua_State
  • gets the current lua_State this is executed in

# reflection.all(): {[index: string]: lua_State}

reflection.all(): {[index: string]: lua_State}
  • gets all instances of lua_State and their names

# reflection.name(lua_State* state): string

reflection.name(lua_State* state): string
  • converts a lua_State to its named counterpart

# reflection.execute(source: string, name: string, state?: lua_State): string?

reflection.execute(source: string, name: string, state?: lua_State): string?
  • executes lua on a lua_State or the current active state its in

# reflection.compile(source: string, name: string): function | string

reflection.compile(source: string, name: string): function | string
  • compiles lua on the the current active state its in

# reflection.open(name: string): lua_State

reflection.open(name: string): lua_State
  • spawns a new lua_State instance or returns one if it already exists
-- creates a new lua_State
local state = reflection.open("lua_State.magic")

-- execute lua right onto the stack
reflection.execute([[
    print("new lua_State boys!")
]], "test", state)

-- you can use basic stack manipulation here as well
print("\nprinting this lua_State's stuff")
reflection.stack(function(L)
    L:pushvalue(-10002)
    L:pushnil()
    while L:next(-2) do
        if L:isstring(-2) then
            print(L:getstring(-2))
        end
        L:pop()
    end
end, state)

-- if you really don't need it, you can close it
reflection.close(state)

# reflection.close(state: lua_State)

reflection.close(state: lua_State)
  • destroys a lua_State instance
  • this won't work on games with built-in lua_State instances

# reflection.stack(func: function(L: lua_State), state?: lua_State): any...

reflection.stack(func: function(L: lua_State), state?: lua_State): any...
  • creates a stack isolated bridge to a lua_State.
  • do note that you don't need to do this but using this reduces the risk of overflows.
-- this is in menu-state or another lua-state
local other_state = reflection.get("other_state")

local res = reflection.stack(function(L)
    L:pushnumber(20)
    local num = L:tonumber(-1)
    L:pop()
    return num
end, other_state)

print(res) -- 20

-- you can also do it outside the stack isolation if needed:
L:pushnumber(20)
local res = L:tonumber(-1)
L:pop()

print(res) -- 20

# Lua State

These are interface & function definitions for how we handle lua_State

# L:execute(source: string, name: string): string?

L:execute(source: string, name: string): string?
  • executes lua on a lua_State.

# L:compile(source: string, name: string): string?

L:compile(source: string, name: string): string?
  • compiles lua on a lua_State.
  • do note that doing this will push the function onto the stack, consider seeing more in CAPI.

# L:stack(func: function(L: lua_State)): any?

L:stack(func: function(L: lua_State)): any?
  • creates a stack isolated bridge to a lua_State.
  • do note that you don't need to do this but using this reduces the risk of overflows.

# L:api(): API

L:api(): API
  • Pushes the API onto the stack for access

# L:call(inputs: number, outputs: number)

L:call(inputs: number, outputs: number)
  • Calls a function thats pushed onto the stack
  • This will consume the no. inputs first, then execute the functions
L:reflection.compile("print(({...})[1])", "example")
L:pushstring("hello world")
L:call(1, 0) -- calls "example" with "hello world"

# L:pop(count?: number)

L:pop(count?: number)
  • Pops a value off of the stack at the top

# L:remove(index: number)

L:remove(index: number)
  • Removes a value at an index off of the stack

# L:length(index: number): number

L:length(index: number): number
  • Used to get the length of a value

# L:next(index: number): boolean

L:next(index: number): boolean
  • A pair-style iterator function for going through table
L:newtable() -- example

L:pushnil() -- push an invalid key to jump-start the iterator
while L:next(-2) do -- target table for key-grabbing
    -- this pushes 2 values onto the stack, -1: value, -2: key
    L:pop(); -- pop the value, keep the key so 'next' can keep going
end

L:pop() -- pop table off stack

# L:pushany(value: any)

L:pushany(value: any)
  • Transfers any datatype from your environment to the stack

# L:getany(index: number): any

L:getany(index: number): any
  • Transfers any datatype from the stack to your environment

# L:gettop(): number

L:gettop(): number
  • Gets the current size of the Lua stack
  • This is useful for vararg style handling

# L:gettype(index: number): number

L:gettype(index: number): number
  • Gets the type ID of a given value

# L:gettypename(index: number): string

L:gettypename(index: number): string
  • Gets the typename of a given value

# L:newtable()

L:newtable()
  • Generates a blank table and pushes it onto the stack

# L:newref(index: number): number

L:newref(index: number): number
  • Creates a reference link to a value
  • This will make the value immune to the garbage collector

# L:pushref(reference: number)

L:pushref(reference: number)
  • Pushes the referenced value back onto the stack

# L:rmref(reference: number)

L:rmref(reference: number)
  • Removes the referenced value from registry

# L:getupvalue(index: number, id: number): string

L:getupvalue(index: number, id: number): string
  • Gets the "upvalue" of a function at the top of the stack
  • Upvalues are values passed to a function not as a parameter, but by reference

# L:setupvalue(index: number, id: number): string

L:setupvalue(index: number, id: number): string
  • Sets the "upvalue" of a function at the top of the stack

# L:getfenv(index: number)

L:getfenv(index: number)
  • Grabs the ENV and pushes it onto the stack
  • You can use this to manipulate the environment

# L:setfenv(index: number)

L:setfenv(index: number)
  • Sets the ENV of a functions at the index
  • This consumes the table you provide it at the top of the stack
  • You can use this to manipulate the environment

# L:getmetatable(index: number): boolean

L:getmetatable(index: number): boolean
  • Grabs the metatable of a table or userdata, and pushes it onto the stack
  • The boolean is provided for if it fails to grab the metatable

# L:setmetatable(index: number)

L:setmetatable(index: number)
  • Sets the metatable of a table or userdata at the index
  • This consumes the table you provide it at the top of the stack

# L:getfield(index: number, key: string)

L:getfield(index: number, key: string)
  • Gets the value from a table and pushes it onto the stack

# L:setfield(index: number, key: string)

L:setfield(index: number, key: string)
  • Sets a value in a table by key
  • Index corresponds to where the table is on the stack

# L:gettable(index: number)

L:gettable(index: number)
  • Gets the value from a table and pushes it onto the stack
  • This will consume a value just before it to determine the key

# L:settable(index: number)

L:settable(index: number)
  • Sets a value in a table by the key at the top of the stack
  • The top of the stack is the key, and top-1 is the value

# L:rawget(index: number)

L:rawget(index: number)
  • Gets the value from a table and pushes it onto the stack
  • This will consume a value just before it to determine the key
  • Unlike gettable this will not invoke metatable callbacks

# L:rawset(index: number)

L:rawset(index: number)
  • Sets a value in a table by the key at the top of the stack
  • The top of the stack is the key, and top-1 is the value
  • Unlike settable this will not invoke metatable callbacks

# L:getboolean(index: number): boolean

L:getboolean(index: number): boolean
  • Attempts to get a boolean value from the Lua stack
  • If the type is invalid, an error will be thrown

# L:getnumber(index: number)

L:getnumber(index: number)
  • Attempts to get a number value from the Lua stack
  • If the type is invalid, an error will be thrown

# L:getstring(index: number)

L:getstring(index: number)
  • Attempts to get a string value from the Lua stack
  • If the type is invalid, an error will be thrown

# L:pushboolean(value: boolean)

L:pushboolean(value: boolean)
  • Pushes a boolean onto the stack

# L:pushnil()

L:pushnil()
  • Pushes a nil value onto the stack

# L:pushnumber(value: number)

L:pushnumber(value: number)
  • Pushes a number onto the stack

# L:pushstring(value: string)

L:pushstring(value: string)
  • Pushes a string onto the stack

# L:pushfunction(value: function)

L:pushfunction(value: function)
  • Pushes a function onto the stack

# L:pushtable(value: table)

L:pushtable(value: table)
  • Pushes a table onto the stack

# L:pushvalue(index: number)

L:pushvalue(index: number)
  • Makes a copy of a value at the index and pushes it to the top of the stack

# L:isboolean(index: number): boolean

L:isboolean(index: number): boolean
  • Checks if the value at index on the stack is a boolean

# L:iscfunction(index: number): boolean

L:iscfunction(index: number): boolean
  • Checks if the value at index on the stack is a cfunction

# L:isfunction(index: number): boolean

L:isfunction(index: number): boolean
  • Checks if the value at index on the stack is a function

# L:islightuserdata(index: number): boolean

L:islightuserdata(index: number): boolean
  • Checks if the value at index on the stack is a lightuserdata

# L:isnil(index: number): boolean

L:isnil(index: number): boolean
  • Checks if the value at index on the stack is nil

# L:isnumber(index: number): boolean

L:isnumber(index: number): boolean
  • Checks if the value at index on the stack is a number

# L:isstring(index: number): boolean

L:isstring(index: number): boolean
  • Checks if the value at index on the stack is a string

# L:istable(index: number): boolean

L:istable(index: number): boolean
  • Checks if the value at index on the stack is a table

# L:isthread(index: number): boolean

L:isthread(index: number): boolean
  • Checks if the value at index on the stack is a thread

# L:isuserdata(index: number): boolean

L:isuserdata(index: number): boolean
  • Checks if the value at index on the stack is a userdata

# L:istype(index: number, type: number): boolean

L:istype(index: number, type: number): boolean
  • Checks if the value matches a specific type ID