Skip to content

Commit

Permalink
init: initial work on luau bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
CompeyDev committed Jul 17, 2024
0 parents commit e17ec03
Show file tree
Hide file tree
Showing 14 changed files with 482 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[{*.go,Makefile,.gitmodules,go.mod,go.sum}]
indent_style = tab

[*.md]
indent_style = tab
trim_trailing_whitespace = false

[*.{yml,yaml,json}]
indent_style = space
indent_size = 2

[*.{js,jsx,ts,tsx,css,less,sass,scss,vue,py}]
indent_style = space
indent_size = 4
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* -text
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Mac OS X files
.DS_Store

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/

# Dependency directories (remove the comment below to include it)
# vendor/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "internal/luau"]
path = internal/luau
url = https://github.com/luau-lang/luau
13 changes: 13 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"files.associations": {
"lobject.h": "c",
"lualib.h": "c",
"lua.h": "c",
"luaconf.h": "c",
"cstdint": "c",
"stdlib.h": "c"
},
"go.toolsEnvVars": {
"CGO_LDFLAGS_ALLOW":".*"
}
}
9 changes: 9 additions & 0 deletions examples/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# `/examples`

Examples for your applications and/or public libraries.

Examples:

* https://github.com/nats-io/nats.go/tree/master/examples
* https://github.com/docker-slim/docker-slim/tree/master/examples
* https://github.com/hashicorp/packer/tree/master/examples
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/CompeyDev/gluau

go 1.19
18 changes: 18 additions & 0 deletions internal/clua.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdio.h>
#include <lua.h>
#include <_cgo_export.h>

void* clua_alloc(void* ud, void *ptr, size_t osize, size_t nsize)
{
return (void*) go_allocf((GoUintptr) ud,(GoUintptr) ptr, osize, nsize);
}

lua_State* clua_newstate(void* goallocf)
{
return lua_newstate(&clua_alloc, goallocf);
}

l_noret cluaL_errorL(lua_State* L, char* msg)
{
return luaL_error(L, msg);
}
6 changes: 6 additions & 0 deletions internal/clua.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <stdlib.h>
#include <lua.h>

void* clua_alloc(void* ud, void *ptr, size_t osize, size_t nsize);
lua_State* clua_newstate(void* goallocf);
l_noret cluaL_errorL(lua_State* L, char* msg);
187 changes: 187 additions & 0 deletions internal/lauxlib.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package internal

/*
#cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include -I${SRCDIR}
#include <lua.h>
#include <lualib.h>
#include <stdlib.h>
#include <clua.h>
// From https://golang-nuts.narkive.com/UsNENgyt/cgo-how-to-pass-string-to-char-array
static char** makeCharArray(int size) {
return calloc(sizeof(char*), size);
}
static void setArrayString(char** a, char* s, int n) {
a[n] = s;
}
static void freeCharArray(char** a, int size) {
int i;
for (i = 0; i < size; i++)
free(a[i]);
free(a);
}
*/
import "C"
import "unsafe"

type luaL_Reg C.luaL_Reg

func LRegister(L *C.lua_State, libname string, l *luaL_Reg) {
clibname := C.CString(libname)
defer C.free(unsafe.Pointer(clibname))

C.luaL_register(L, clibname, (*C.luaL_Reg)(l))
}

func LGetMetaField(L *C.lua_State, obj int32, e string) int32 {
ce := C.CString(e)
defer C.free(unsafe.Pointer(ce))

return int32(C.luaL_getmetafield(L, C.int(obj), ce))
}

func LCallMeta(L *C.lua_State, obj int32, e string) int32 {
ce := C.CString(e)
defer C.free(unsafe.Pointer(ce))

return int32(C.luaL_callmeta(L, C.int(obj), ce))
}

func LTypeError(L *C.lua_State, narg int32, tname string) {
ctname := C.CString(tname)
defer C.free(unsafe.Pointer(ctname))

C.luaL_typeerrorL(L, C.int(narg), ctname)
}

func LArgError(L *C.lua_State, narg int32, extramsg string) {
cextramsg := C.CString(extramsg)
defer C.free(unsafe.Pointer(cextramsg))

C.luaL_argerrorL(L, C.int(narg), cextramsg)
}

func LCheckLString(L *C.lua_State, narg int32, l *uint64) string {
p := C.luaL_checklstring(L, C.int(narg), (*C.size_t)(l))
defer C.free(unsafe.Pointer(p))

return C.GoString(p)
}

func LOptLString(L *C.lua_State, narg int32, def string, l *uint64) string {
cdef := C.CString(def)
defer C.free(unsafe.Pointer(cdef))

p := C.luaL_optlstring(L, C.int(narg), cdef, (*C.ulong)(l))
defer C.free(unsafe.Pointer(p))

return C.GoString(p)
}

func LCheckNumber(L *C.lua_State, narg int32) lua_Number {
return lua_Number(C.luaL_checknumber(L, C.int(narg)))
}

func LOptNumber(L *C.lua_State, narg int32, def lua_Number) lua_Number {
return lua_Number(C.luaL_optnumber(L, C.int(narg), C.lua_Number(def)))
}

func LCheckBoolean(L *C.lua_State, narg int32) bool {
return C.luaL_checkboolean(L, C.int(narg)) != 0
}

func LOptBoolean(L *C.lua_State, narg int32, def bool) bool {
cdef := C.int(0)
if def {
cdef = C.int(1)
}

return C.luaL_optboolean(L, C.int(narg), cdef) != 0
}

func LCheckInteger(L *C.lua_State, narg int32) lua_Integer {
return lua_Integer(C.luaL_checkinteger(L, C.int(narg)))
}

func LOptInteger(L *C.lua_State, narg int32, def lua_Integer) lua_Integer {
return lua_Integer(C.luaL_optinteger(L, C.int(narg), C.lua_Integer(def)))
}

func LCheckUnsigned(L *C.lua_State, narg int32) lua_Unsigned {
return lua_Unsigned(C.luaL_checkunsigned(L, C.int(narg)))
}

func LOptUnsigned(L *C.lua_State, narg int32, def lua_Unsigned) lua_Unsigned {
return lua_Unsigned(C.luaL_optunsigned(L, C.int(narg), C.lua_Unsigned(def)))
}

func LCheckVector(L *C.lua_State, narg int32) *float32 {
return (*float32)(C.luaL_checkvector(L, C.int(narg)))
}

func LOptVector(L *C.lua_State, narg int32, def *float32) *float32 {
return (*float32)(C.luaL_optvector(L, C.int(narg), (*C.float)(def)))
}

func LCheckStack(L *C.lua_State, sz int32, msg string) {
cmsg := C.CString(msg)
defer C.free(unsafe.Pointer(cmsg))

C.luaL_checkstack(L, C.int(sz), cmsg)
}

func LCheckType(L *C.lua_State, narg int32, t int32) {
C.luaL_checktype(L, C.int(narg), C.int(t))
}

func LCheckAny(L *C.lua_State, narg int32) {
C.luaL_checkany(L, C.int(narg))
}

func LNewMetatable(L *C.lua_State, tname string) bool {
ctname := C.CString(tname)
defer C.free(unsafe.Pointer(ctname))

return C.luaL_newmetatable(L, ctname) != 0
}

func LCheckUdata(L *C.lua_State, ud int32, tname string) unsafe.Pointer {
ctname := C.CString(tname)
defer C.free(unsafe.Pointer(ctname))

return C.luaL_checkudata(L, C.int(ud), ctname)
}

func LCheckBuffer(L *C.lua_State, narg int32, len *uint64) unsafe.Pointer {
return C.luaL_checkbuffer(L, C.int(narg), (*C.size_t)(len))
}

func LWhere(L *C.lua_State, lvl int32) {
C.luaL_where(L, C.int(lvl))
}

// NOTE: It's not possible to pass varargs from Go->C via cgo, so instead we
// expect the user to format the message and hand it over to us, which we
// pass to luaL_errorL. This is an inconsistency with the actual C API, but
// there isn't really anything we can do.
func LErrorL(L *C.lua_State, msg string) {
cmsg := C.CString(msg)
defer C.free(unsafe.Pointer(cmsg))

C.cluaL_errorL(L, cmsg)
}

func LCheckOption(L *C.lua_State, narg int32, def string, lst []string) int32 {
cdef := C.CString(def)
defer C.free(unsafe.Pointer(cdef))

clst := C.makeCharArray(C.int(len(lst)))
defer C.freeCharArray(clst, C.int(len(lst)))
for i, s := range lst {
C.setArrayString(clst, C.CString(s), C.int(i))
}

return int32(C.luaL_checkoption(L, C.int(narg), cdef, clst))
}
Loading

0 comments on commit e17ec03

Please sign in to comment.