diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8f7b53e --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +_cgo1_.o +_cgo_.o +_cgo_defun.6 +_cgo_defun.c +_cgo_export.c +_cgo_export.h +_cgo_export.o +_cgo_gotypes.go +_cgo_import.c +_cgo_main.c +_cgo_main.o +_obj/ +golua.o +lauxlib.cgo1.go +lauxlib.cgo2.c +lauxlib.cgo2.o +lua.cgo1.go +lua.cgo2.c +lua.cgo2.o +*.[568] +lua_defs.* diff --git a/Makefile b/Makefile index adf77e6..c69bbae 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,53 @@ +# Copyright 2009 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. -LUA51_DIR=lua51 +include $(GOROOT)/src/Make.inc -all: $(LUA51_DIR)/_obj/lua51.a examples +LUA_INCLUDE_DIR=/usr/include/lua5.1/ +LUA_LIB_DIR=/usr/lib/ -$(LUA51_DIR)/_obj/lua51.a: - cd $(LUA51_DIR) && make +CGO_CFLAGS+=-I$(LUA_INCLUDE_DIR) +CGO_DEPS=_cgo_export.o +CGO_LDFLAGS+=-L$(LUA_LIB_DIR) -lm -llua5.1 +CGO_OFILES=\ + golua.o \ -examples: install - cd example && make +TARG=golua + +CGOFILES=\ + lua.go \ + lauxlib.go \ + lua_defs.go + +CLEANFILES+=lua-5.1.4/src/*.o\ + example/*.8\ + example/basic\ + example/alloc\ + example/panic\ + example/userdata\ + +LUA_HEADERS=lua.h lauxlib.h lualib.h +LUA_HEADER_FILES:=$(patsubst %,$(LUA_INCLUDE_DIR)%,$(LUA_HEADERS)) +LUA_INCLUDE_DIRECTIVES:=$(patsubst %,//\#include <%>\n, $(LUA_HEADERS)) + +include $(GOROOT)/src/Make.pkg -clean: - cd example && make clean - cd $(LUA51_DIR) && make clean +all: install examples -install: - cd $(LUA51_DIR) && make install - +%: install %.go + $(QUOTED_GOBIN)/$(GC) $*.go + $(QUOTED_GOBIN)/$(LD) -o $@ $*.$O + +golua.o: golua.c + gcc $(CGO_CFLAGS) $(_CGO_CFLAGS_$(GOARCH)) -fPIC $(CFLAGS) -c golua.c -o golua.o + +lua_defs.go: + echo "package golua;" > lua_defs.go + echo "$(LUA_INCLUDE_DIRECTIVES)" "import \"C\"" >> lua_defs.go + echo "const (" >> lua_defs.go + cat $(LUA_HEADER_FILES) | grep '#define LUA' | sed 's/#define/ /' | sed 's/\([A-Z_][A-Z_]*\)[[:space:]]*.*/\1 = C.\1/' >> lua_defs.go + echo ")" >> lua_defs.go + +examples: install + cd example && make diff --git a/README b/README index 7a68e52..c966e71 100644 --- a/README +++ b/README @@ -2,31 +2,15 @@ Go Bindings for the lua C API Simplest way to install: -#goinstall -u github.com/afitz/golua -#cd $GOROOT/src/pkg/github.com/afitz/golua -#make install +$ goinstall -u github.com/abneptis/golua +$ cd $GOROOT/src/pkg/github.com/abneptis/golua +$ make install - -Configuration Variables ------------------------ -LUA51_LIBNAME -default: lua5.1 -used if LUA51_LIB_DIR is defined - -LUA51_INCLUDE_DIR -default: undefined -defining this overrides the pkg-config mechanism to find the lua cflags - -LUA51_LIB_DIR -default: undefined -defining this overrides the pkg-config mechanism to create the LD_FLAGS - -Licensing +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. - - - +The Lua license can be found in the source and is available online: + http://www.lua.org/license.html diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..b18adb2 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,5 @@ +*.[5678vqo] +alloc +basic +panic +userdata diff --git a/example/alloc.go b/example/alloc.go index 212665c..cd46262 100644 --- a/example/alloc.go +++ b/example/alloc.go @@ -1,6 +1,6 @@ package main -import lua "lua51" +import lua "golua" import "unsafe" import "fmt" diff --git a/example/basic.go b/example/basic.go index 2276822..008e80a 100644 --- a/example/basic.go +++ b/example/basic.go @@ -1,16 +1,16 @@ package main -import "lua51" +import "golua" import "fmt" -func test(L *lua51.State) int { +func test(L *golua.State) int { fmt.Println("hello world! from go!"); return 0; } -func test2(L *lua51.State) int { - arg := lua51.CheckInteger(L,-1); - argfrombottom := lua51.CheckInteger(L,1); +func test2(L *golua.State) int { + arg := golua.CheckInteger(L,-1); + argfrombottom := golua.CheckInteger(L,1); fmt.Print("test2 arg: "); fmt.Println(arg); fmt.Print("from bottom: "); @@ -19,12 +19,12 @@ func test2(L *lua51.State) int { } func main() { - var L *lua51.State; + var L *golua.State; - L = lua51.NewState(); + L = golua.NewState(); L.OpenLibs(); - L.GetField(lua51.LUA_GLOBALSINDEX, "print"); + L.GetField(golua.LUA_GLOBALSINDEX, "print"); L.PushString("Hello World!"); L.Call(1,0); diff --git a/example/panic.go b/example/panic.go index 15cc50c..5d2cd9b 100644 --- a/example/panic.go +++ b/example/panic.go @@ -1,6 +1,6 @@ package main -import lua "lua51" +import lua "golua" import "fmt" func test(L *lua.State) int { diff --git a/example/userdata.go b/example/userdata.go index 620803f..72af8a2 100644 --- a/example/userdata.go +++ b/example/userdata.go @@ -1,6 +1,6 @@ package main -import lua "lua51" +import lua "golua" import "unsafe" import "fmt" diff --git a/lua51/golua.c b/golua.c similarity index 94% rename from lua51/golua.c rename to golua.c index c8ad53e..b2b1dc1 100644 --- a/lua51/golua.c +++ b/golua.c @@ -46,7 +46,7 @@ int gchook_wrapper(lua_State* L) GoInterface* gi = clua_getgostate(L); if(fid != NULL) return golua_gchook(*gi,*fid); - + printf("GCHook failed\n"); //TODO: try udata or whatever, after impl return 0; @@ -220,3 +220,14 @@ void clua_openos(lua_State* L){ lua_pushstring(L,"os"); lua_call(L, 1, 0); } + +void clua_hook_function(lua_State *L, lua_Debug *ar) { + lua_checkstack(L, 2); + lua_pushstring(L, "Lua execution quantum exceeded"); + lua_error(L); +} + +void clua_setexecutionlimit(lua_State* L, int n) { + lua_sethook(L, &clua_hook_function, LUA_MASKCOUNT, n); +} + diff --git a/lua51/golua.h b/golua.h similarity index 94% rename from lua51/golua.h rename to golua.h index ec60e83..d561613 100644 --- a/lua51/golua.h +++ b/golua.h @@ -22,5 +22,4 @@ void clua_openpackage(lua_State* L); void clua_openstring(lua_State* L); void clua_opentable(lua_State* L); void clua_openos(lua_State* L); - - +void clua_setexecutionlimit(lua_State* L, int n); diff --git a/lua51/lauxlib.go b/lauxlib.go similarity index 67% rename from lua51/lauxlib.go rename to lauxlib.go index 2503fdb..1656e79 100644 --- a/lua51/lauxlib.go +++ b/lauxlib.go @@ -1,8 +1,9 @@ -package lua51 +package golua //#include //#include //#include +//#include //#include "golua.h" import "C" import "unsafe" @@ -14,12 +15,16 @@ import "unsafe" func ArgCheck(L *State, cond bool, narg int, extramsg string) { if cond { - C.luaL_argerror(L.s, C.int(narg), C.CString(extramsg)); + Cextramsg := C.CString(extramsg) + defer C.free(unsafe.Pointer(Cextramsg)) + C.luaL_argerror(L.s, C.int(narg), Cextramsg) } } func ArgError(L *State, narg int, extramsg string) int { - return int(C.luaL_argerror(L.s,C.int(narg),C.CString(extramsg))); + Cextramsg := C.CString(extramsg) + defer C.free(unsafe.Pointer(Cextramsg)) + return int(C.luaL_argerror(L.s,C.int(narg),Cextramsg)); } //type luaL_Buffer @@ -27,7 +32,9 @@ func ArgError(L *State, narg int, extramsg string) int { //luaL_buffinit func CallMeta(L *State, obj int, e string) int { - return int(C.luaL_callmeta(L.s,C.int(obj),C.CString(e))); + Ce := C.CString(e) + defer C.free(unsafe.Pointer(Ce)) + return int(C.luaL_callmeta(L.s,C.int(obj),Ce)) } func CheckAny(L *State, narg int) { @@ -55,8 +62,11 @@ func CheckOption(L *State, narg int, def string, lst []string) int { func CheckType(L *State, narg int, t int) { C.luaL_checktype(L.s,C.int(narg),C.int(t)); } + func CheckUdata(L *State, narg int, tname string) unsafe.Pointer { - return unsafe.Pointer(C.luaL_checkudata(L.s,C.int(narg),C.CString(tname))); + Ctname := C.CString(tname) + defer C.free(unsafe.Pointer(Ctname)) + return unsafe.Pointer(C.luaL_checkudata(L.s,C.int(narg),Ctname)) } //true if no errors, false otherwise @@ -83,33 +93,51 @@ func FmtError(L *State, fmt string, args...interface{}) int { //returns false if no such metatable or no such field func GetMetaField(L *State, obj int, e string) bool { - return C.luaL_getmetafield(L.s,C.int(obj),C.CString(e)) != 0; + Ce := C.CString(e) + defer C.free(unsafe.Pointer(Ce)) + return C.luaL_getmetafield(L.s,C.int(obj),Ce) != 0; } //TODO: rename better... clashes with lua_getmetatable func LGetMetaTable(L *State, tname string) { - //C.luaL_getmetatable(L.s,C.CString(tname)); - C.lua_getfield(L.s,LUA_REGISTRYINDEX,C.CString(tname)); + Ctname := C.CString(tname) + defer C.free(unsafe.Pointer(Ctname)) + C.lua_getfield(L.s,LUA_REGISTRYINDEX,Ctname); } func GSub(L *State, s string, p string, r string) string { - return C.GoString(C.luaL_gsub(L.s, C.CString(s), C.CString(p), C.CString(r))); + Cs := C.CString(s) + Cp := C.CString(p) + Cr := C.CString(r) + defer func(){ + C.free(unsafe.Pointer(Cs)) + C.free(unsafe.Pointer(Cp)) + C.free(unsafe.Pointer(Cr)) + }() + + return C.GoString(C.luaL_gsub(L.s, Cs, Cp, Cr)) } //TODO: luaL_loadbuffer func (L *State) LoadFile(filename string) int { - return int(C.luaL_loadfile(L.s,C.CString(filename))); + Cfilename := C.CString(filename) + defer C.free(unsafe.Pointer(Cfilename)) + return int(C.luaL_loadfile(L.s,Cfilename)); } func (L *State) LoadString(s string) int { - return int(C.luaL_loadstring(L.s,C.CString(s))); + Cs := C.CString(s) + defer C.free(unsafe.Pointer(Cs)) + return int(C.luaL_loadstring(L.s,Cs)) } //returns false if registry already contains key tname func (L *State) NewMetaTable(tname string) bool { - return C.luaL_newmetatable(L.s, C.CString(tname)) != 0; + Ctname := C.CString(tname) + defer C.free(unsafe.Pointer(Ctname)) + return C.luaL_newmetatable(L.s, Ctname) != 0; } func NewState() *State { @@ -132,7 +160,9 @@ func (L *State) OptNumber(narg int, d float64) float64 { func (L *State) OptString(narg int, d string) string { var length C.size_t; - return C.GoString(C.luaL_optlstring(L.s,C.int(narg),C.CString(d),&length)); + Cd := C.CString(d) + defer C.free(unsafe.Pointer(Cd)) + return C.GoString(C.luaL_optlstring(L.s,C.int(narg),Cd,&length)); } //luaL_prepbuffer @@ -150,7 +180,9 @@ func LTypename(L *State, index int) string { //TODO: decide if we actually want this renamed func TypeError(L *State, narg int, tname string) int { - return int(C.luaL_typerror(L.s,C.int(narg),C.CString(tname))); + Ctname := C.CString(tname) + defer C.free(unsafe.Pointer(Ctname)) + return int(C.luaL_typerror(L.s,C.int(narg),Ctname)) } func Unref(L *State, t int, ref int) { diff --git a/lua51/lua.go b/lua.go similarity index 95% rename from lua51/lua.go rename to lua.go index 9cb9e64..c942d0b 100644 --- a/lua51/lua.go +++ b/lua.go @@ -1,12 +1,11 @@ -package lua51 +package golua //#include //#include "golua.h" +//#include import "C" import "unsafe" -//TODO: remove -import "fmt" @@ -101,7 +100,6 @@ func golua_callgofunction(L interface{}, fid uint) int { func golua_gchook(L interface{}, id uint) int { L1 := L.(*State); L1.unregister(id); - fmt.Printf("GC id: %d\n",id); return 0; } @@ -184,7 +182,6 @@ func (L *State) AtPanic(panicf GoFunction) (oldpanicf GoFunction) { return nil; } - func (L *State) Call(nargs int, nresults int) { C.lua_call(L.s,C.int(nargs),C.int(nresults)); } @@ -228,7 +225,9 @@ func (L *State) GC(what, data int) int { return int(C.lua_gc(L.s, C.int(what), C func (L *State) GetfEnv(index int) { C.lua_getfenv(L.s, C.int(index)) } func (L *State) GetField(index int, k string) { - C.lua_getfield(L.s, C.int(index), C.CString(k)) + Ck := C.CString(k) + defer C.free(unsafe.Pointer(Ck)) + C.lua_getfield(L.s, C.int(index), Ck) } func (L *State) GetGlobal(name string) { L.GetField(LUA_GLOBALSINDEX, name) } @@ -341,7 +340,9 @@ func (L *State) PushBoolean(b bool) { } func (L *State) PushString(str string) { - C.lua_pushstring(L.s,C.CString(str)); + Cstr := C.CString(str) + defer C.free(unsafe.Pointer(Cstr)) + C.lua_pushstring(L.s,Cstr) } func (L *State) PushInteger(n int) { @@ -410,11 +411,15 @@ func (L *State) SetfEnv(index int) { } func (L *State) SetField(index int, k string) { - C.lua_setfield(L.s, C.int(index), C.CString(k)); + Ck := C.CString(k) + defer C.free(unsafe.Pointer(Ck)) + C.lua_setfield(L.s, C.int(index), Ck) } func (L *State) SetGlobal(name string) { - C.lua_setfield(L.s, C.int(LUA_GLOBALSINDEX), C.CString(name)) + Cname := C.CString(name) + defer C.free(unsafe.Pointer(Cname)) + C.lua_setfield(L.s, C.int(LUA_GLOBALSINDEX), Cname) } func (L *State) SetMetaTable(index int) { @@ -518,3 +523,7 @@ func (L *State) OpenTable() { func (L *State) OpenOS() { C.clua_openos(L.s); } + +func (L *State) SetExecutionLimit(instrNumber int) { + C.clua_setexecutionlimit(L.s, C.int(instrNumber)); +} diff --git a/lua51/Makefile b/lua51/Makefile deleted file mode 100644 index 8b95a45..0000000 --- a/lua51/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -include $(GOROOT)/src/Make.inc - -CGO_OFILES+=golua.o - -ifndef LUA51_LIBNAME -LUA51_LIBNAME=lua5.1 -endif - -ifndef LUA51_INCLUDE_DIR -CGO_CFLAGS+=`pkg-config --cflags $(LUA51_LIBNAME)` -LUA51_INCLUDE_DIR:=$(shell pkg-config --cflags-only-I $(LUA51_LIBNAME) | sed 's/-I//' | sed 's/[ ]*$$//') -else -CGO_CFLAGS+=-I$(LUA51_INCLUDE_DIR) -endif - -ifndef LUA51_LIB_DIR -CGO_LDFLAGS+=`pkg-config --libs $(LUA51_LIBNAME)` -else -CGO_LDFLAGS+=-L$(LUA51_LIB_DIR) -l$(LUA51_LIBNAME) -endif - -TARG=lua51 - -CGOFILES=\ - lua.go \ - lauxlib.go \ - lua_defs.go - -CLEANFILES+=lua_defs.go - -LUA_HEADERS=lua.h lauxlib.h lualib.h -LUA_HEADER_FILES:=$(patsubst %,$(LUA51_INCLUDE_DIR)/%,$(LUA_HEADERS)) -LUA_INCLUDE_DIRECTIVES:=$(patsubst %,//\#include <%>\n, $(LUA_HEADERS)) - - -include $(GOROOT)/src/Make.pkg - -%: install %.go - $(QUOTED_GOBIN)/$(GC) $*.go - $(QUOTED_GOBIN)/$(LD) -o $@ $*.$O - -golua.o: golua.c - gcc $(CGO_CFLAGS) $(_CGO_CFLAGS_$(GOARCH)) -fPIC $(CFLAGS) -c golua.c -o golua.o - -lua_defs.go: - echo "package lua51;" > lua_defs.go - echo "$(LUA_INCLUDE_DIRECTIVES)" "import \"C\"" >> lua_defs.go -# echo "import \"C\"" >> lua_defs.go - cat $(LUA_HEADER_FILES) | grep '#define LUA' | sed 's/#define/const/' | sed 's/\([A-Z_][A-Z_]*\)[\t ].*/\1 = C.\1/' >> lua_defs.go -