lei/internal/lua.go

309 lines
7 KiB
Go
Raw Normal View History

2024-07-17 12:39:44 +01:00
package internal
/*
#cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include
// #cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++
2024-07-17 12:39:44 +01:00
#include <lua.h>
#include <lualib.h>
#include <stdlib.h>
#include "clua.h"
2024-07-17 12:39:44 +01:00
*/
import "C"
import "unsafe"
type LuaNumber float64
type LuaInteger int32
type LuaUnsigned int32
2024-07-17 12:39:44 +01:00
type LuaState = C.lua_State
type LuaCFunction func(L *LuaState) int32
type LuaContinuation func(L *LuaState, status int32) int32
2024-07-17 12:39:44 +01:00
type LuaUDestructor = func(*C.void)
type LuaDestructor = func(L *LuaState, _ unsafe.Pointer)
2024-07-17 12:39:44 +01:00
// type LuaAlloc = func(ud, ptr *C.void, osize, nsize C.size_t) *C.void
type LuaAlloc = func(ptr unsafe.Pointer, osize, nsize uint64) unsafe.Pointer
2024-07-17 12:39:44 +01:00
//export go_allocf
func go_allocf(fp uintptr, ptr uintptr, osize uint64, nsize uint64) uintptr {
p := ((*((*LuaAlloc)(unsafe.Pointer(fp))))(unsafe.Pointer(ptr), osize, nsize))
2024-07-17 12:39:44 +01:00
return uintptr(p)
}
//
// ==================
// VM state
// ==================
//
func NewState(ud unsafe.Pointer) *LuaState {
2024-07-17 12:39:44 +01:00
return C.clua_newstate(unsafe.Pointer(ud))
}
func LuaClose(L *LuaState) {
2024-07-17 12:39:44 +01:00
C.lua_close(L)
}
func NewThread(L *LuaState) *LuaState {
2024-07-17 12:39:44 +01:00
return C.lua_newthread(L)
}
func MainThread(L *LuaState) *LuaState {
2024-07-17 12:39:44 +01:00
return C.lua_mainthread(L)
}
func ResetThread(L *LuaState) {
2024-07-17 12:39:44 +01:00
C.lua_resetthread(L)
}
func IsThreadReset(L *LuaState) bool {
2024-07-17 12:39:44 +01:00
return C.lua_isthreadreset(L) != 0
}
//
// ==================
// VM Stack
// ==================
//
func AbsIndex(L *LuaState, idx int32) int32 {
return int32(C.lua_absindex(L, C.int(idx)))
2024-07-17 12:39:44 +01:00
}
func GetTop(L *LuaState) int32 {
return int32(C.lua_gettop(L))
2024-07-17 12:39:44 +01:00
}
func SetTop(L *LuaState, idx int32) {
C.lua_settop(L, C.int(idx))
2024-07-17 12:39:44 +01:00
}
func PushValue(L *LuaState, idx int32) {
C.lua_pushvalue(L, C.int(idx))
2024-07-17 12:39:44 +01:00
}
func Remove(L *LuaState, idx int32) {
C.lua_remove(L, C.int(idx))
2024-07-17 12:39:44 +01:00
}
func Insert(L *LuaState, idx int32) {
C.lua_insert(L, C.int(idx))
2024-07-17 12:39:44 +01:00
}
func Replace(L *LuaState, idx int32) {
C.lua_replace(L, C.int(idx))
2024-07-17 12:39:44 +01:00
}
func CheckStack(L *LuaState, sz int32) bool {
return C.lua_checkstack(L, C.int(sz)) != 0
2024-07-17 12:39:44 +01:00
}
func RawCheckStack(L *LuaState, sz int32) {
C.lua_rawcheckstack(L, C.int(sz))
2024-07-17 12:39:44 +01:00
}
func XMove(from, to *LuaState, n int32) {
C.lua_xmove(from, to, C.int(n))
2024-07-17 12:39:44 +01:00
}
func XPush(from, to *LuaState, idx int32) {
C.lua_xpush(from, to, C.int(idx))
2024-07-17 12:39:44 +01:00
}
//
// ======================
// Stack Values
// ======================
//
func IsNumber(L *LuaState, idx int32) bool {
return C.lua_isnumber(L, C.int(idx)) != 0
2024-07-17 12:39:44 +01:00
}
func IsString(L *LuaState, idx int32) bool {
return C.lua_isstring(L, C.int(idx)) != 0
2024-07-17 12:39:44 +01:00
}
func IsCFunction(L *LuaState, idx int32) bool {
return C.lua_iscfunction(L, C.int(idx)) != 0
2024-07-17 12:39:44 +01:00
}
func IsLFunction(L *LuaState, idx int32) bool {
return C.lua_isLfunction(L, C.int(idx)) != 0
2024-07-17 12:39:44 +01:00
}
func IsUserData(L *LuaState, idx int32) bool {
return C.lua_isuserdata(L, C.int(idx)) != 0
2024-07-17 12:39:44 +01:00
}
func Type(L *LuaState, idx int32) bool {
return C.lua_type(L, C.int(idx)) != 0
2024-07-17 12:39:44 +01:00
}
func TypeName(L *LuaState, tp int32) string {
return C.GoString(C.lua_typename(L, C.int(tp)))
2024-07-17 12:39:44 +01:00
}
func Equal(L *LuaState, idx1, idx2 int32) bool {
return C.lua_equal(L, C.int(idx1), C.int(idx2)) != 0
2024-07-17 12:39:44 +01:00
}
func RawEqual(L *LuaState, idx1, idx2 int32) bool {
return C.lua_rawequal(L, C.int(idx1), C.int(idx2)) != 0
2024-07-17 12:39:44 +01:00
}
func LessThan(L *LuaState, idx1, idx2 int32) bool {
return C.lua_lessthan(L, C.int(idx1), C.int(idx2)) != 0
2024-07-17 12:39:44 +01:00
}
func ToNumberX(L *LuaState, idx int32, isnum bool) LuaNumber {
2024-07-17 12:39:44 +01:00
isnumInner := C.int(0)
if isnum {
isnumInner = C.int(1)
}
return LuaNumber(C.lua_tonumberx(L, C.int(idx), &isnumInner))
2024-07-17 12:39:44 +01:00
}
func ToIntegerX(L *LuaState, idx int32, isnum bool) LuaInteger {
2024-07-17 12:39:44 +01:00
isnumInner := C.int(0)
if isnum {
isnumInner = C.int(1)
}
return LuaInteger(C.lua_tointegerx(L, C.int(idx), &isnumInner))
2024-07-17 12:39:44 +01:00
}
func ToUnsignedX(L *LuaState, idx int32, isnum bool) LuaUnsigned {
2024-07-17 12:39:44 +01:00
isnumInner := C.int(0)
if isnum {
isnumInner = C.int(1)
}
return LuaUnsigned(C.lua_tounsignedx(L, C.int(idx), &isnumInner))
2024-07-17 12:39:44 +01:00
}
func ToVector(L *LuaState, idx int32) {
2024-07-17 19:55:35 +01:00
C.lua_tovector(L, C.int(idx))
}
func ToBoolean(L *LuaState, idx int32) bool {
2024-07-17 19:55:35 +01:00
return C.lua_toboolean(L, C.int(idx)) != 0
}
func ToLString(L *LuaState, idx int32, len *uint64) string {
2024-07-17 19:55:35 +01:00
return C.GoString(C.lua_tolstring(L, C.int(idx), (*C.size_t)(len)))
}
func ToStringAtom(L *LuaState, idx int32, atom *int32) string {
2024-07-17 19:55:35 +01:00
return C.GoString(C.lua_tostringatom(L, C.int(idx), (*C.int)(atom)))
}
func NameCallAtom(L *LuaState, atom *int32) string {
2024-07-17 19:55:35 +01:00
return C.GoString(C.lua_namecallatom(L, (*C.int)(atom)))
}
func ObjLen(L *LuaState, idx int32) uint64 {
2024-07-17 19:55:35 +01:00
return uint64(C.lua_objlen(L, C.int(idx)))
}
func ToCFunction(L *LuaState, idx int32) LuaCFunction {
2024-07-17 19:55:35 +01:00
p := unsafe.Pointer(C.lua_tocfunction(L, C.int(idx)))
if p == C.NULL {
return nil
}
return *(*LuaCFunction)(p)
2024-07-17 19:55:35 +01:00
}
func ToLightUserdata(L *LuaState, idx int32) unsafe.Pointer {
2024-07-17 19:55:35 +01:00
return unsafe.Pointer(C.lua_tolightuserdata(L, C.int(idx)))
}
func ToLightUserdataTagged(L *LuaState, idx int32, tag int32) unsafe.Pointer {
2024-07-17 19:55:35 +01:00
return unsafe.Pointer(C.lua_tolightuserdatatagged(L, C.int(idx), C.int(tag)))
}
func ToUserdata(L *LuaState, idx int32) unsafe.Pointer {
2024-07-17 19:55:35 +01:00
return unsafe.Pointer(C.lua_touserdata(L, C.int(idx)))
}
func ToUserdataTagged(L *LuaState, idx int32, tag int32) unsafe.Pointer {
2024-07-17 19:55:35 +01:00
return unsafe.Pointer(C.lua_touserdatatagged(L, C.int(idx), C.int(tag)))
}
func UserdataTag(L *LuaState, idx int32) int32 {
2024-07-17 19:55:35 +01:00
return int32(C.lua_userdatatag(L, C.int(idx)))
}
func LightUserdataTag(L *LuaState, idx int32) int32 {
2024-07-17 19:55:35 +01:00
return int32(C.lua_lightuserdatatag(L, C.int(idx)))
}
func ToThread(L *LuaState, idx int32) *LuaState {
2024-07-17 19:55:35 +01:00
return C.lua_tothread(L, C.int(idx))
}
func ToBuffer(L *LuaState, idx int32, len *uint64) unsafe.Pointer {
2024-07-17 19:55:35 +01:00
return unsafe.Pointer(C.lua_tobuffer(L, C.int(idx), (*C.size_t)(len)))
}
func ToPointer(L *LuaState, idx int32) unsafe.Pointer {
2024-07-17 19:55:35 +01:00
return unsafe.Pointer(C.lua_topointer(L, C.int(idx)))
}
// =======================
// Stack Manipulation
// =======================
func PushNil(L *LuaState) {
2024-07-17 19:55:35 +01:00
C.lua_pushnil(L)
}
func PushNumber(L *LuaState, n LuaNumber) {
2024-07-17 19:55:35 +01:00
C.lua_pushnumber(L, C.lua_Number(n))
}
func PushInteger(L *LuaState, n LuaInteger) {
2024-07-17 19:55:35 +01:00
C.lua_pushinteger(L, C.lua_Integer(n))
}
func PushUnsigned(L *LuaState, n LuaUnsigned) {
C.lua_pushunsigned(L, C.lua_Unsigned(n))
}
func PushLString(L *LuaState, s string, l uint64) {
cs := C.CString(s)
defer C.free(unsafe.Pointer(cs))
C.lua_pushlstring(L, cs, C.size_t(l))
}
func PushString(L *LuaState, s string) {
cs := C.CString(s)
defer C.free(unsafe.Pointer(cs))
C.lua_pushstring(L, cs)
}
// NOTE: We can't have lua_pushfstringL, since varadic
// arguments from Go->C isn't something that is possible.
// func PushFStringL(L *lua_State, fmt string) {}
func PushCClosureK(L *LuaState, f LuaCFunction, debugname string, nup int32, cont LuaContinuation) {
cdebugname := C.CString(debugname)
defer C.free(unsafe.Pointer(cdebugname))
var ccont unsafe.Pointer
if cont == nil {
ccont = C.NULL
} else {
ccont = unsafe.Pointer(&cont)
}
C.clua_pushcclosurek(L, unsafe.Pointer(&f), cdebugname, C.int(nup), ccont)
}
2024-07-17 19:55:35 +01:00
2024-07-17 12:39:44 +01:00
// TODO: Rest of it