Go bindings for Lua C API - in progress

Go Bindings for the lua C API

Build Status

Simplest way to install:

# go get github.com/aarzilli/golua/lua

You can then try to run the examples:

$ cd golua/_example/
$ go run basic.go
$ go run alloc.go
$ go run panic.go
$ go run userdata.go

This library is configured using build tags. By default it will look for a library (or "shared object") called:

  • lua5.1 on Linux and macOS
  • lua on Windows
  • lua-5.1 on FreeBSD

If this doesn't work -tags luadash5.1 can be used to force lua-5.1, and -tags llua can be used to force lua.

If you want to statically link to liblua.a you can do that with -tags luaa. Luajit can also be used by specifying -tags luajit.

The library uses lua5.1 by default but also supports lua5.2 by specifying -tags lua52, lua5.3 by specifying -tags lua53, and lua5.4 by specifying -tags lua54.

QUICK START

Create a new Virtual Machine with:

L := lua.NewState()
L.OpenLibs()
defer L.Close()

Lua's Virtual Machine is stack based, you can call lua functions like this:

// push "print" function on the stack
L.GetGlobal("print")
// push the string "Hello World!" on the stack
L.PushString("Hello World!")
// call print with one argument, expecting no results
L.Call(1, 0)

Of course this isn't very useful, more useful is executing lua code from a file or from a string:

// executes a string of lua code
err := L.DoString("...")
// executes a file
err = L.DoFile(filename)

You will also probably want to publish go functions to the virtual machine, you can do it by:

func adder(L *lua.State) int {
	a := L.ToInteger(1)
	b := L.ToInteger(2)
	L.PushInteger(a + b)
	return 1 // number of return values
}

func main() {
	L := lua.NewState()
	defer L.Close()
	L.OpenLibs()

	L.Register("adder", adder)
	L.DoString("print(adder(2, 2))")
}

ON ERROR HANDLING

Lua's exceptions are incompatible with Go, golua works around this incompatibility by setting up protected execution environments in lua.State.DoString, lua.State.DoFile and lua.State.Call and turning every exception into a Go panic.

This means that:

  1. In general you can't do any exception handling from Lua, pcall and xpcall are renamed to unsafe_pcall and unsafe_xpcall. They are only safe to be called from Lua code that never calls back to Go. Use at your own risk.

  2. The call to lua.State.Error, present in previous versions of this library, has been removed as it is nonsensical

  3. Method calls on a newly created lua.State happen in an unprotected environment, if Lua throws an exception as a result your program will be terminated. If this is undesirable perform your initialization like this:

func LuaStateInit(L *lua.State) int {
	… initialization goes herereturn 0
}

…
L.PushGoFunction(LuaStateInit)
err := L.Call(0, 0)
…

ON THREADS AND COROUTINES

'lua.State' is not thread safe, but the library itself is. Lua's coroutines exist but (to my knowledge) have never been tested and are likely to encounter the same problems that errors have, use at your own peril.

ODDS AND ENDS

  • If you want to build against lua5.2, lua5.3, or lua5.4 use the build tags lua52, lua53, or lua54 respectively.
  • Compiling from source yields only a static link library (liblua.a), you can either produce the dynamic link library on your own or use the luaa build tag.

LUAJIT

To link with luajit-2.0.x, you can use CGO_CFLAGS and CGO_LDFLAGS environment variables

$ CGO_CFLAGS=`pkg-config luajit --cflags`
$ CGO_LDFLAGS=`pkg-config luajit --libs-only-L`
$ go get -f -u -tags luajit github.com/aarzilli/golua/lua

CONTRIBUTORS

  • Adam Fitzgerald (original author)
  • Alessandro Arzilli
  • Steve Donovan
  • Harley Laue
  • James Nurmi
  • Ruitao
  • Xushiwei
  • Isaint
  • hsinhoyeh
  • Viktor Palmkvist
  • HongZhen Peng
  • Admin36
  • Pierre Neidhardt (@Ambrevar)
  • HuangWei (@huangwei1024)
  • Adam Saponara

SEE ALSO

  • Luar is a reflection layer on top of golua API providing a simplified way to publish go functions to a Lua VM.
  • lunatico is a reflection layer that allows you to push and read Go values to a Lua VM without understanding the Lua stack.
  • Golua unicode is an extension library that adds unicode support to golua and replaces lua regular expressions with re2.

Licensing

GoLua is released under the MIT license. Please see the LICENSE file for more information.

Lua is Copyright (c) Lua.org, PUC-Rio. All rights reserved.

Owner
Alessandro Arzilli
silence is foo
Alessandro Arzilli
Comments
  • ToThread implementation

    ToThread implementation

    I did an implementation of ToThread. It appears to work, but I would glad to have it reviewed by someone with more experience. If it seems satisfactory, it might be pleasant to add it to golua.

    In place https://github.com/aarzilli/golua/blob/master/lua/lua.go#L568 of the TODO, I wrote:

    // lua_tothread
    func (L *State) ToThread(index int) *State {
        s := &State{s: (*C.lua_State)(unsafe.Pointer(C.lua_tothread(L.s, C.int(index))))}
        registerGoState(s)
        return s
    }
    

    In particular, is the registerGoState(s) call the correct thing to do? I'm not at all certain. When I register fmt.Printf with one thread, invoking it calls MakeChan registered with the main vm, so it seems that wires are getting crossed. But that might just be a different bug elsewhere.

  • using the library from a vendor directory

    using the library from a vendor directory

    Hi,

    When I try to use this from a vendor directory I get:

    vendor/github.com/aarzilli/golua/lua/golua.go:6:17: fatal error: lua.h: No such file or directory #include <lua.h> ^ compilation terminated.

    What I am doing wrong?

    Thanks

  • Building for 5.3

    Building for 5.3

    OS: Arch Linux Lua version: 5.3.4

    Building for 5.3 with the go install -tags llua command, I get the following error:

    github.com/aarzilli/golua/lua
    # github.com/aarzilli/golua/lua
    In file included from ./lua.h:16:0,
                     from ./golua.go:6,
                     from $WORK/github.com/aarzilli/golua/lua/_obj/_cgo_export.c:3:
    ./luaconf.h:192:34: fatal error: lua5.3-deb-multiarch.h: No such file or directory
     #include "lua5.3-deb-multiarch.h"
                                      ^
    

    It works if I comment the deb related lines in luaconf.h:

    /* This defines DEB_HOST_MULTIARCH */
    // #include "lua5.3-deb-multiarch.h"
    
    #define LUA_ROOT	"/usr/local/"
    #define LUA_ROOT2	"/usr/"
    #define LUA_LDIR	LUA_ROOT "share/lua/" LUA_VDIR "/"
    #define LUA_LDIR2	LUA_ROOT2 "share/lua/" LUA_VDIR "/"
    #define LUA_CDIR	LUA_ROOT "lib/lua/" LUA_VDIR "/"
    // #define LUA_CDIR2	LUA_ROOT2 "lib/" DEB_HOST_MULTIARCH "/lua/" LUA_VDIR "/"
    #define LUA_CDIR3	LUA_ROOT2 "lib/lua/" LUA_VDIR "/"
    

    Compared to the 5.2 branch, there are header files both in lua/ and in lua/lua/. Why is it so? What are the differences?

    Why not using the system headers by the way? If I try removing the embedded headers in lua/, I get the following error:

    github.com/aarzilli/golua/lua
    # github.com/aarzilli/golua/lua
    /tmp/go-build411086781/github.com/aarzilli/golua/lua/_obj/lua.cgo2.o: In function `_cgo_1901af7180ba_Cfunc_lua_insert':
    ./cgo-gcc-prolog:594: undefined reference to `lua_insert'
    /tmp/go-build411086781/github.com/aarzilli/golua/lua/_obj/lua.cgo2.o: In function `_cgo_1901af7180ba_Cfunc_lua_remove':
    ./cgo-gcc-prolog:957: undefined reference to `lua_remove'
    /tmp/go-build411086781/github.com/aarzilli/golua/lua/_obj/lua.cgo2.o: In function `_cgo_1901af7180ba_Cfunc_lua_replace':
    ./cgo-gcc-prolog:971: undefined reference to `lua_replace'
    /tmp/go-build411086781/github.com/aarzilli/golua/lua/_obj/c-golua.o: In function `callback_function':
    ./c-golua.c:77: undefined reference to `lua_remove'
    collect2: error: ld returned 1 exit status
    

    Could you enlighten me here?

  • clua_pushcallback has been added to allow definining metamethods with Go...

    clua_pushcallback has been added to allow definining metamethods with Go...

    clua_pushcallback has been added to allow definining metamethods with Go functions.

    This adds the ability to push Go functions as C closures. It's code hand patched from @stevedonovan's golua repo. Specifically: https://github.com/stevedonovan/golua/commit/3a27ba88ab6637e70ae243ab29aa768e1734f697 without the changes to GoInterface.

    His luar project, which uses golua, then only needs small changes to become compatible with your golua fork.

  • go test crash on osx with luajit-2.1-beta3, unexpected SIGSEGV / SIGBUS on TestCheckStringFail

    go test crash on osx with luajit-2.1-beta3, unexpected SIGSEGV / SIGBUS on TestCheckStringFail

    Golua looks pretty awesome. I hear people using with LuaJIT just fine, but I'm trying it for the first time and not having any luck. I built against luajit-2.1-beta3 on my mac, go1.91 and osx 10.12.5.

    I tried both 64-bit and 32-bit builds. Both crash with fatal error: unexpected signal during runtime execution 64-bit complains of SIGSEGV. 32-bit complains of SIGBUS. Both are crashing on the TestCheckStringFail test.

    64-bit crash:

    jaten@Jasons-MacBook-Pro ~/go/src/github.com/glycerine/golua/lua (master) $ go test -v
    go test -v
    === RUN   TestGoStruct
    --- PASS: TestGoStruct (0.00s)
    === RUN   TestCheckStringSuccess
    --- PASS: TestCheckStringSuccess (0.00s)
    === RUN   TestCheckStringFail
    fatal error: unexpected signal during runtime execution
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x7fff091d3828 pc=0x7fff091d3828]
    
    runtime stack:
    runtime.throw(0x414fe08, 0x2a)
    	/usr/local/go/src/runtime/panic.go:605 +0x95
    runtime.sigpanic()
    	/usr/local/go/src/runtime/signal_unix.go:351 +0x2b8
    
    goroutine 7 [syscall, locked to thread]:
    runtime.cgocall(0x40fee50, 0xc420049dc8, 0x40f0100)
    	/usr/local/go/src/runtime/cgocall.go:132 +0xe4 fp=0xc420049d80 sp=0xc420049d40 pc=0x4003a14
    github.com/glycerine/golua/lua._Cfunc_lua_pcall(0x4580378, 0xffffffff00000000, 0x1, 0x0)
    	github.com/glycerine/golua/lua/_test/_obj_test/_cgo_gotypes.go:1102 +0x4d fp=0xc420049dc8 sp=0xc420049d80 pc=0x40f562d
    github.com/glycerine/golua/lua.(*State).pcall.func1(0x4580378, 0xffffffff00000000, 0x1, 0x1)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:175 +0x78 fp=0xc420049e00 sp=0xc420049dc8 pc=0x40fb878
    github.com/glycerine/golua/lua.(*State).pcall(0xc4200667c0, 0x0, 0xffffffffffffffff, 0x1, 0x40fd7e0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:175 +0x49 fp=0xc420049e30 sp=0xc420049e00 pc=0x40f8d19
    github.com/glycerine/golua/lua.(*State).callEx(0xc4200667c0, 0x0, 0xffffffffffffffff, 0x4302501, 0x0, 0x0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:194 +0xd7 fp=0xc420049ea8 sp=0xc420049e30 pc=0x40f8e17
    github.com/glycerine/golua/lua.(*State).Call(0xc4200667c0, 0x0, 0xffffffffffffffff, 0x0, 0xffffd8ee)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:207 +0x44 fp=0xc420049ee8 sp=0xc420049ea8 pc=0x40f9044
    github.com/glycerine/golua/lua.(*State).DoString(0xc4200667c0, 0x4148e9c, 0x7, 0x41516d8, 0x406b1d6)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lauxlib.go:107 +0x190 fp=0xc420049f58 sp=0xc420049ee8 pc=0x40f8540
    github.com/glycerine/golua/lua.TestCheckStringFail(0xc4200a22d0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua_test.go:75 +0xb0 fp=0xc420049fa8 sp=0xc420049f58 pc=0x40f2bb0
    testing.tRunner(0xc4200a22d0, 0x41516e0)
    	/usr/local/go/src/testing/testing.go:746 +0xd0 fp=0xc420049fd0 sp=0xc420049fa8 pc=0x40b78a0
    runtime.goexit()
    	/usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420049fd8 sp=0xc420049fd0 pc=0x4058c51
    created by testing.(*T).Run
    	/usr/local/go/src/testing/testing.go:789 +0x2de
    
    goroutine 1 [chan receive]:
    testing.(*T).Run(0xc4200a2000, 0x414afdb, 0x13, 0x41516e0, 0x406b101)
    	/usr/local/go/src/testing/testing.go:790 +0x2fc
    testing.runTests.func1(0xc4200a2000)
    	/usr/local/go/src/testing/testing.go:1004 +0x64
    testing.tRunner(0xc4200a2000, 0xc42005bde0)
    	/usr/local/go/src/testing/testing.go:746 +0xd0
    testing.runTests(0xc42000c0c0, 0x41fcfe0, 0xa, 0xa, 0x41ff4a0)
    	/usr/local/go/src/testing/testing.go:1002 +0x2d8
    testing.(*M).Run(0xc42005bf18, 0xc42005bf70)
    	/usr/local/go/src/testing/testing.go:921 +0x111
    main.main()
    	github.com/glycerine/golua/lua/_test/_testmain.go:62 +0xdb
    exit status 2
    FAIL	github.com/glycerine/golua/lua	0.158s
    jaten@Jasons-MacBook-Pro ~/go/src/github.com/glycerine/golua/lua (master) $ ls
    
    

    32-bit crash:

    jaten@Jasons-MacBook-Pro ~/go/src/github.com/glycerine/golua/lua (master) $ ./lua.test -test.v
    ./lua.test -test.v
    === RUN   TestGoStruct
    --- PASS: TestGoStruct (0.00s)
    === RUN   TestCheckStringSuccess
    --- PASS: TestCheckStringSuccess (0.00s)
    === RUN   TestCheckStringFail
    fatal error: unexpected signal during runtime execution
    [signal SIGBUS: bus error code=0x2 addr=0x43e18b0 pc=0x43e18b0]
    
    runtime stack:
    runtime.throw(0x41bb8c5, 0x2a)
    	/usr/local/go/src/runtime/panic.go:605 +0x76
    runtime.sigpanic()
    	/usr/local/go/src/runtime/signal_unix.go:351 +0x252
    
    goroutine 7 [syscall, locked to thread]:
    runtime.cgocall(0x4113530, 0x15233e84, 0x4188940)
    	/usr/local/go/src/runtime/cgocall.go:132 +0x7b fp=0x15233e5c sp=0x15233e44 pc=0x4003ffb
    github.com/glycerine/golua/lua._Cfunc_lua_pcall(0x43de1c0, 0x0, 0xffffffff, 0x1, 0x0)
    	github.com/glycerine/golua/lua/_test/_obj_test/_cgo_gotypes.go:1100 +0x39 fp=0x15233e84 sp=0x15233e5c pc=0x410ae49
    github.com/glycerine/golua/lua.(*State).pcall.func1(0x43de1c0, 0x0, 0xffffffff, 0x1, 0x0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:175 +0x6d fp=0x15233ea4 sp=0x15233e84 pc=0x4110dfd
    github.com/glycerine/golua/lua.(*State).pcall(0x15260640, 0x0, 0xffffffff, 0x1, 0x0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:175 +0x3f fp=0x15233ec0 sp=0x15233ea4 pc=0x410e4af
    github.com/glycerine/golua/lua.(*State).callEx(0x15260640, 0x0, 0xffffffff, 0x4700001, 0x0, 0x0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:194 +0xd0 fp=0x15233f0c sp=0x15233ec0 pc=0x410e5a0
    github.com/glycerine/golua/lua.(*State).Call(0x15260640, 0x0, 0xffffffff, 0x0, 0x0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua.go:207 +0x40 fp=0x15233f30 sp=0x15233f0c pc=0x410e770
    github.com/glycerine/golua/lua.(*State).DoString(0x15260640, 0x41b4923, 0x7, 0x0, 0x0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lauxlib.go:112 +0x159 fp=0x15233f70 sp=0x15233f30 pc=0x410dab9
    github.com/glycerine/golua/lua.TestCheckStringFail(0x152a01b0)
    	/Users/jaten/go/src/github.com/glycerine/golua/lua/lua_test.go:75 +0x9d fp=0x15233fb0 sp=0x15233f70 pc=0x4107fad
    testing.tRunner(0x152a01b0, 0x41bd0a0)
    	/usr/local/go/src/testing/testing.go:746 +0xce fp=0x15233fe8 sp=0x15233fb0 pc=0x40c0dde
    runtime.goexit()
    	/usr/local/go/src/runtime/asm_386.s:1635 +0x1 fp=0x15233fec sp=0x15233fe8 pc=0x4052111
    created by testing.(*T).Run
    	/usr/local/go/src/testing/testing.go:789 +0x3b0
    
    goroutine 1 [chan receive]:
    testing.(*T).Run(0x152a01b0, 0x41b6a9f, 0x13, 0x41bd0a0, 0x96f00)
    	/usr/local/go/src/testing/testing.go:790 +0x3c9
    testing.runTests.func1(0x152a0000)
    	/usr/local/go/src/testing/testing.go:1004 +0xa9
    testing.tRunner(0x152a0000, 0x15255e84)
    	/usr/local/go/src/testing/testing.go:746 +0xce
    testing.runTests(0x1520c060, 0x4255740, 0xa, 0xa, 0x100)
    	/usr/local/go/src/testing/testing.go:1002 +0x28a
    testing.(*M).Run(0x1527e0f0, 0x0)
    	/usr/local/go/src/testing/testing.go:921 +0x26f
    main.main()
    	github.com/glycerine/golua/lua/_test/_testmain.go:62 +0x99
    jaten@Jasons-MacBook-Pro ~/go/src/github.com/glycerine/golua/lua (master) $ file ./lua.test 
    file ./lua.test 
    ./lua.test: Mach-O executable i386
    jaten@Jasons-MacBook-Pro ~/go/src/github.com/glycerine/golua/lua (master) $ go version 
    go version 
    go version go1.9.1 darwin/amd64
    jaten@Jasons-MacBook-Pro ~/go/src/github.com/glycerine/golua/lua (master) $ 
    

    I'm using the latest master branch, 24fe5b510806231d29be66de88ab2ce608311d33 which is tip currently.

  • undefined reference issue

    undefined reference issue

    when i run go get -u -tags llua github.com/aarzilli/golua/lua,the result is the ld report many undefined reference.such as below:

    /usr/local/lib/liblua.a(lvm.o): In function Arith': lvm.c:(.text+0x485): undefined reference topow' lvm.c:(.text+0x4b4): undefined reference to floor' /usr/local/lib/liblua.a(lvm.o): In functionluaV_execute': lvm.c:(.text+0x22c1): undefined reference to floor' lvm.c:(.text+0x23de): undefined reference topow' /usr/local/lib/liblua.a(lmathlib.o): In function math_tan': lmathlib.c:(.text+0x9f): undefined reference totan' /usr/local/lib/liblua.a(lmathlib.o): In function math_tanh': lmathlib.c:(.text+0xcf): undefined reference totanh' /usr/local/lib/liblua.a(lmathlib.o): In function math_sqrt': lmathlib.c:(.text+0x11c): undefined reference tosqrt' /usr/local/lib/liblua.a(lmathlib.o): In function math_sin': lmathlib.c:(.text+0x13f): undefined reference tosin' /usr/local/lib/liblua.a(lmathlib.o): In function math_sinh': lmathlib.c:(.text+0x16f): undefined reference tosinh' /usr/local/lib/liblua.a(lmathlib.o): In function math_floor': lmathlib.c:(.text+0x29f): undefined reference tofloor' /usr/local/lib/liblua.a(lmathlib.o): In function math_random': lmathlib.c:(.text+0x3be): undefined reference tofloor' lmathlib.c:(.text+0x406): undefined reference to floor' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_pow': lmathlib.c:(.text+0x48a): undefined reference to pow' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_log': lmathlib.c:(.text+0x50f): undefined reference to log' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_log10': lmathlib.c:(.text+0x53f): undefined reference to log10' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_fmod': lmathlib.c:(.text+0x666): undefined reference to fmod' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_exp': lmathlib.c:(.text+0x67f): undefined reference to exp' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_cos': lmathlib.c:(.text+0x6af): undefined reference to cos' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_cosh': lmathlib.c:(.text+0x6df): undefined reference to cosh' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_ceil': lmathlib.c:(.text+0x70f): undefined reference to ceil' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_atan': lmathlib.c:(.text+0x73f): undefined reference to atan' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_atan2': lmathlib.c:(.text+0x78a): undefined reference to atan2' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_asin': lmathlib.c:(.text+0x7bf): undefined reference to asin' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_acos': lmathlib.c:(.text+0x7ef): undefined reference to acos' /usr/local/lib/liblua.a(loadlib.o): In functionll_loadfunc': loadlib.c:(.text+0x878): undefined reference to dlsym' loadlib.c:(.text+0x8d1): undefined reference todlopen' loadlib.c:(.text+0x8e9): undefined reference to dlerror' loadlib.c:(.text+0x900): undefined reference todlerror' /usr/local/lib/liblua.a(loadlib.o): In function gctm': loadlib.c:(.text+0xcbc): undefined reference todlclose' /usr/local/lib/liblua.a(lcode.o): In function codearith': lcode.c:(.text+0x1118): undefined reference topow' lcode.c:(.text+0x1140): undefined reference to `floor' collect2: ld returned 1 exit status

    what shoud i do?

  • go build fail with Lua 5.1 built from source code

    go build fail with Lua 5.1 built from source code

    my environment is ubuntu 12.04 and golang version is 1.2. if my lua 5.1 is installed from apt-get, your golua library works well for me. for example: sudo apt-get install lua5.1 go get -u github.com/aarzilli/golua/lua and go build, which works well.

    but something goes wrong if I installed lua5.1 from source code. What I have done is : cd lua-5.1 make linux ( because I use linux platform) make linux install

    when I am doing go build on your package: I have encountered the following error message: github.com/aarzilli/golua/lua /usr/local/lib/liblua.a(lvm.o): In function Arith': lvm.c:(.text+0x475): undefined reference topow' lvm.c:(.text+0x4a4): undefined reference to floor' /usr/local/lib/liblua.a(lvm.o): In functionluaV_execute': lvm.c:(.text+0x222f): undefined reference to floor' lvm.c:(.text+0x232b): undefined reference topow' /usr/local/lib/liblua.a(lmathlib.o): In function math_tan': lmathlib.c:(.text+0x9f): undefined reference totan' /usr/local/lib/liblua.a(lmathlib.o): In function math_tanh': lmathlib.c:(.text+0xcf): undefined reference totanh' /usr/local/lib/liblua.a(lmathlib.o): In function math_sqrt': lmathlib.c:(.text+0x11c): undefined reference tosqrt' /usr/local/lib/liblua.a(lmathlib.o): In function math_sin': lmathlib.c:(.text+0x13f): undefined reference tosin' /usr/local/lib/liblua.a(lmathlib.o): In function math_sinh': lmathlib.c:(.text+0x16f): undefined reference tosinh' /usr/local/lib/liblua.a(lmathlib.o): In function math_floor': lmathlib.c:(.text+0x29f): undefined reference tofloor' /usr/local/lib/liblua.a(lmathlib.o): In function math_random': lmathlib.c:(.text+0x3bf): undefined reference tofloor' lmathlib.c:(.text+0x407): undefined reference to floor' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_pow': lmathlib.c:(.text+0x48a): undefined reference to pow' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_log': lmathlib.c:(.text+0x50f): undefined reference to log' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_log10': lmathlib.c:(.text+0x53f): undefined reference to log10' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_fmod': lmathlib.c:(.text+0x65c): undefined reference to fmod' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_exp': lmathlib.c:(.text+0x67f): undefined reference to exp' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_cos': lmathlib.c:(.text+0x6af): undefined reference to cos' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_cosh': lmathlib.c:(.text+0x6df): undefined reference to cosh' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_ceil': lmathlib.c:(.text+0x70f): undefined reference to ceil' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_atan': lmathlib.c:(.text+0x73f): undefined reference to atan' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_atan2': lmathlib.c:(.text+0x78a): undefined reference to atan2' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_asin': lmathlib.c:(.text+0x7bf): undefined reference to asin' /usr/local/lib/liblua.a(lmathlib.o): In functionmath_acos': lmathlib.c:(.text+0x7ef): undefined reference to acos' /usr/local/lib/liblua.a(loadlib.o): In functionll_loadfunc': loadlib.c:(.text+0x878): undefined reference to dlsym' loadlib.c:(.text+0x8c9): undefined reference todlerror' loadlib.c:(.text+0x8e9): undefined reference to dlopen' loadlib.c:(.text+0x8ff): undefined reference todlerror' /usr/local/lib/liblua.a(loadlib.o): In function gctm': loadlib.c:(.text+0xc8c): undefined reference todlclose' /usr/local/lib/liblua.a(lcode.o): In function codearith': lcode.c:(.text+0x1018): undefined reference topow' lcode.c:(.text+0x1040): undefined reference to `floor' collect2: error: ld returned 1 exit status

    After done some search, I founded that the following modification (add ldl and lm libraries) can be compiled without any error message: diff --git a/lua/lua.go b/lua/lua.go index 3704e13..06088f6 100644 --- a/lua/lua.go +++ b/lua/lua.go @@ -8,7 +8,7 @@ package lua /* #cgo CFLAGS: -Ilua #cgo llua LDFLAGS: -llua -#cgo linux,!llua LDFLAGS: -llua5.1 +#cgo linux,!llua LDFLAGS: -llua -ldl -lm #cgo darwin LDFLAGS: -llua #cgo freebsd LDFLAGS: -llua

    should I submit a pull request for it? any suggestions? thanks

  • mulitple lua_state in each goroutine, will panic

    mulitple lua_state in each goroutine, will panic

    func worker() {
    	L := lua.NewState()
    	defer L.Close()
    	L.OpenLibs()
    	L.DoFile("./test.lua")
    }
    func test() {
    	count := 1000
    	ch := make(chan int, count)
    	for i := 0; i < count; i++ {
    		go worker()
    	}
            // wait all
    }
    

    if count < 500, it is ok. but bigger count, it will panic. so wired!

  • alloc func may crash when reference an address on stack

    alloc func may crash when reference an address on stack

    before change: func NewStateAlloc(f Alloc) *State { ls := C.clua_newstate(unsafe.Pointer(&f)) return newState(ls) }

    f is an value on stack, and C.clua_newstate store its address by unsafe.Pointer(&f), when lua need access this function by deference its stored address, may crash

    after change: func NewStateAlloc(f *Alloc) *State { ls := C.clua_newstate(unsafe.Pointer(f)) return newState(ls) }

  • Runtime crash using LuaJIT

    Runtime crash using LuaJIT

    I have tried using golua with LuaJIT 2.0.4 without success due to the unit tests crashing. I tired both static and dynamic lyncing and confirmed with ldd on the output of go test -c. As soon as I return to using standard Lua the tests pass. Here is an example crash while using dynamic linking:

    fatal error: unexpected signal during runtime execution
    [signal 0xb code=0x1 addr=0x7fe7838180a0 pc=0x7fe7838180a0]
    
    runtime stack:
    runtime.throw(0x5da100, 0x2a)
        /home/user/go/src/runtime/panic.go:527 +0x90
    runtime.sigpanic()
        /home/user/go/src/runtime/sigpanic_unix.go:12 +0x5a
    
    goroutine 7 [syscall, locked to thread]:
    runtime.cgocall(0x405c70, 0xc82002ddb0, 0x0)
        /home/user/go/src/runtime/cgocall.go:120 +0x11b fp=0xc82002dd68 sp=0xc82002dd38
    tb/golua/lua._Cfunc_lua_pcall(0x40f11378, 0xffffffff00000000, 0x1, 0x0)
        ??:0 +0x39 fp=0xc82002ddb0 sp=0xc82002dd68
    tb/golua/lua.(*State).pcall(0xc820010a40, 0x0, 0xffffffffffffffff, 0x1, 0x884060)
        /home/user/corp/src/tb/golua/lua/lua.go:182 +0x45 fp=0xc82002ddd8 sp=0xc82002ddb0
    tb/golua/lua.(*State).callEx(0xc820010a40, 0x0, 0xffffffffffffffff, 0x1579001, 0x0, 0x0)
        /home/user/corp/src/tb/golua/lua/lua.go:201 +0xfb fp=0xc82002de48 sp=0xc82002ddd8
    tb/golua/lua.(*State).Call(0xc820010a40, 0x0, 0xffffffffffffffff, 0x0, 0x0)
        /home/user/corp/src/tb/golua/lua/lua.go:214 +0x48 fp=0xc82002de80 sp=0xc82002de48
    tb/golua/lua.(*State).DoString(0xc820010a40, 0x5a3900, 0x7, 0x0, 0x0)
        /home/user/corp/src/tb/golua/lua/lauxlib.go:106 +0x1c7 fp=0xc82002dee8 sp=0xc82002de80
    tb/golua/lua.TestCheckStringFail(0xc82009c120)
        /home/user/corp/src/tb/golua/lua/lua_test.go:71 +0xbf fp=0xc82002df78 sp=0xc82002dee8
    testing.tRunner(0xc82009c120, 0x8742d0)
        /home/user/go/src/testing/testing.go:456 +0x98 fp=0xc82002dfb0 sp=0xc82002df78
    runtime.goexit()
        /home/user/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc82002dfb8 sp=0xc82002dfb0
    created by testing.RunTests
        /home/user/go/src/testing/testing.go:561 +0x86d
    
    goroutine 1 [chan receive]:
    testing.RunTests(0x5eca30, 0x8742a0, 0xa, 0xa, 0x1)
        /home/user/go/src/testing/testing.go:562 +0x8ad
    testing.(*M).Run(0xc82004fef8, 0xc82000a6c0)
        /home/user/go/src/testing/testing.go:494 +0x70
    main.main()
        tb/golua/lua/_test/_testmain.go:72 +0x116
    
    goroutine 17 [syscall, locked to thread]:
    runtime.goexit()
        /home/user/go/src/runtime/asm_amd64.s:1696 +0x1
    
  • Implement luaL_register

    Implement luaL_register

    I'd like to register a Go library to be called from Lua:

    test.lua

    require "somelib"
    somelib.SomeFunc(params...)
    

    somelib.go

    package somelib
    func SomeFunc(params...)
    

    relevant man docs

    I'm not entirely sure how to get this to work. It seems that lua.Register isn't actually sending the function pointer down to the C api, but storing it locally and using the registry to call functions. How should this work using a library?

    I'd like to help if you could point me in the right direction. Some explanation on how the registry works would be fantastic. I need this pretty soon, so I'll probably start working on this on Monday.

  • How to use golang to implement setLuaPath ?

    How to use golang to implement setLuaPath ?

    int setLuaPath( lua_State* L, const char* path ) { lua_getglobal( L, "package" ); lua_getfield( L, -1, "path" ); // get field "path" from table at top of stack (-1) std::string cur_path = lua_tostring( L, -1 ); // grab path string from top of stack cur_path.append( ";" ); // do your path magic here cur_path.append( path ); lua_pop( L, 1 ); // get rid of the string on the stack we just pushed on line 5 lua_pushstring( L, cur_path.c_str() ); // push the new one lua_setfield( L, -2, "path" ); // set the field "path" in table at -2 with value at top of stack lua_pop( L, 1 ); // get rid of package table from top of stack return 0; // all done! }

  • Support metatables for GoStruct

    Support metatables for GoStruct

    I'm trying to set a metatable to a GoStruct object to be able calling methods in the manner like obj:Foo().

    Currently, testudata() doesn't allow me to do this, requiring the object metatable to be MT_GOINTERFACE or MT_GOFUNCTION.

    I understand the idea of this check, and suggest extending it in the following manner:

    if (!lua_rawequal(L, -1, -2))  /* not the same? */
    
        // Check the second-level metatable
        if (lua_getmetatable(L, -2)) {
            if (lua_rawequal(L, -2, -1)) {  /* equals! */
                lua_pop(L, 3);  /* cleanup */
                return p;
            }
            lua_pop(L, 1);
        }
        // end of new code
    
        p = NULL;
    }
    lua_pop(L, 2);  /* remove both metatables */
    return p;
    

    In addition, the setmetatable() call should be modified (as following), or a new function (e.g. SetGoStructMetaTable) may be introduced if you find this way more appropriate.

    void clua_setmetatable(lua_State* L, unsigned int index)
    {
        if (clua_isgostruct(index)) {
            // Set MT_GOINTERFACE as a second-level metatable for the user metatable
            luaL_getmetatable(L, MT_GOINTERFACE);
            lua_setmetatable(L,-2);
        }
    
        lua_setmetatable(L, index);
        return true;
    }
    
  • Error stack/tracebacks?

    Error stack/tracebacks?

    Hi there!

    little disclaimer first: I'm not terribly familiar with go. I'm trying to take a look around how to use lua with go. I've opened a similar issue with https://github.com/Shopify/go-lua/issues/87 because I had the same problem with (missing) tracebacks.

    I'm struggling a bit on how to get proper tracebacks for errors.

    Giving this hello.lua file containing:

    print("Hello World")
    
    function foo()
      print("Hello, I'm foo!")
      bar()
    end
    
    foo()
    

    …run with lua hello.lua gives me:

    Hello World
    Hello, I'm foo!
    lua: hello.lua:5: attempt to call global 'bar' (a nil value)
    stack traceback:
    	hello.lua:5: in function 'foo'
    	hello.lua:8: in main chunk
    	[C]: in ?
    

    With golua used in file.go:

    package main
    
    import "../lua"
    import "fmt"
    
    func main() {
    	L := lua.NewState()
    	defer L.Close()
    	L.OpenLibs()
    
    	err := L.DoFile("hello.lua")
    
    	fmt.Printf("%v\n", err)
    }
    

    …run with go run file.go gives me:

    Hello World
    Hello, I'm foo!
    hello.lua:5: attempt to call global 'bar' (a nil value)
    

    How can I get a comparable traceback with golua? Something that can be presented to a user. Are there more examples somewhere?

  • C stack overflow in error handler

    C stack overflow in error handler

    When calling a lua function that errors, the C stack is not cleaned up. If the lua function is called many times, it will eventually overflow the stack. Any further calls to the error handler result in the error "error in error handling" being returned.

    This is the smallest test case I could come up with to reproduce it. I'm on Linux using lua 5.1.5 and the most recent version of golua.

    error.go:

    package main
    
    import "github.com/aarzilli/golua/lua"
    import "fmt"
    
    func main() {
        L := lua.NewState()
        L.OpenLibs()
        if err := L.DoFile("error.lua"); err != nil {
            panic(err)
        }
    
        // 120 worked on my machine, might be different for you
        for i:=0; i<120; i++ {
            top := L.GetTop()
            L.GetGlobal("doError")
            err := L.Call(0, lua.LUA_MULTRET)
            if err != nil {
                fmt.Println("error:", err)
                fmt.Println("stack length:", len(L.StackTrace()))
                // fmt.Println("stack:", L.StackTrace())
            }
            L.SetTop(top)
        }
    }
    

    error.lua:

    function doError()
        error("something bad")
    end
    
A Lua VM in Go

A Lua VM in pure Go go-lua is a port of the Lua 5.2 VM to pure Go. It is compatible with binary files dumped by luac, from the Lua reference implement

Dec 31, 2022
GopherLua: VM and compiler for Lua in Go

GopherLua: VM and compiler for Lua in Go. GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting lang

Dec 24, 2022
naive go bindings to the CPython C-API

go-python Naive go bindings towards the C-API of CPython-2. this package provides a go package named "python" under which most of the PyXYZ functions

Jan 5, 2023
Duktape JavaScript engine bindings for Go

Duktape bindings for Go(Golang) Duktape is a thin, embeddable javascript engine. Most of the api is implemented. The exceptions are listed here. Usage

Jan 6, 2023
PHP bindings for the Go programming language (Golang)

PHP bindings for Go This package implements support for executing PHP scripts, exporting Go variables for use in PHP contexts, attaching Go method rec

Jan 1, 2023
Go bindings for Lua C API - in progress

Go Bindings for the lua C API Simplest way to install: # go get github.com/aarzilli/golua/lua You can then try to run the examples: $ cd golua/_examp

Dec 28, 2022
🎀 a nice lil shell for lua people made with go and lua

Hilbish ?? a nice lil shell for lua people made with go and lua It is currently in a mostly beta state but is very much usable (I'm using it right now

Jan 3, 2023
LuaHelper is a High-performance lua plugin, Language Server Protocol for lua.
LuaHelper is a High-performance lua plugin, Language Server Protocol for lua.

LuaHelper is a High-performance lua plugin, Language Server Protocol for lua.

Dec 29, 2022
Heart 💜A high performance Lua web server with a simple, powerful API
Heart 💜A high performance Lua web server with a simple, powerful API

Heart ?? A high performance Lua web server with a simple, powerful API. See the full documentation here. Overview Heart combines Go's fasthttp with Lu

Aug 31, 2022
A Teardown API to Lua stub generator written in Go.

Teardown API Stub Generator This project aims to provide a parser for the XML files at https://www.teardowngame.com/modding/api.xml These files descri

Oct 28, 2022
Go library for interacting with the Discord API (work-in-progress)

zombiezen Go Client for Discord zombiezen.com/go/discord is a WIP Go library for interacting with the Discord API. It differs from DiscordGo by provid

Nov 9, 2022
High level go to Lua binder. Write less, do more.
High level go to Lua binder. Write less, do more.

Binder High level go to Lua binder. Write less, do more. Package binder allows to easily bind to Lua. Based on gopher-lua. Write less, do more! Killer

Oct 9, 2022
A Lua VM in Go

A Lua VM in pure Go go-lua is a port of the Lua 5.2 VM to pure Go. It is compatible with binary files dumped by luac, from the Lua reference implement

Dec 31, 2022
GopherLua: VM and compiler for Lua in Go

GopherLua: VM and compiler for Lua in Go. GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting lang

Dec 24, 2022
:tophat: Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support
:tophat: Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support

Web server with built-in support for QUIC, HTTP/2, Lua, Markdown, Pongo2, HyperApp, Amber, Sass(SCSS), GCSS, JSX, BoltDB (built-in, stores the databas

Jan 1, 2023
A Lua VM in Go

A Lua VM in pure Go go-lua is a port of the Lua 5.2 VM to pure Go. It is compatible with binary files dumped by luac, from the Lua reference implement

Jan 8, 2023
GopherLua: VM and compiler for Lua in Go

GopherLua: VM and compiler for Lua in Go. GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting lang

Dec 31, 2022
GopherLua: VM and compiler for Lua in Go

GopherLua: VM and compiler for Lua in Go. GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal with Lua: Be a scripting lang

Jan 9, 2023
A Lua VM in Go

A Lua VM in pure Go go-lua is a port of the Lua 5.2 VM to pure Go. It is compatible with binary files dumped by luac, from the Lua reference implement

Jan 4, 2023
A Lua 5.3 VM and compiler written in Go.

DCLua - Go Lua Compiler and VM: This is a Lua 5.3 VM and compiler written in Go. This is intended to allow easy embedding into Go programs, with minim

Dec 12, 2022