lua.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. // This package provides access to the excellent lua language interpreter from go code.
  2. //
  3. // Access to most of the functions in lua.h and lauxlib.h is provided as well as additional convenience functions to publish Go objects and functions to lua code.
  4. //
  5. // The documentation of this package is no substitute for the official lua documentation and in many instances methods are described only with the name of their C equivalent
  6. package lua
  7. //#include "golua.h"
  8. import "C"
  9. import (
  10. "fmt"
  11. "unsafe"
  12. )
  13. type LuaStackEntry struct {
  14. Name string
  15. Source string
  16. ShortSource string
  17. CurrentLine int
  18. }
  19. func newState(L *C.lua_State) *State {
  20. newstate := &State{L, 0, make([]interface{}, 0, 8), make([]uint, 0, 8), nil, nil}
  21. registerGoState(newstate)
  22. C.clua_setgostate(L, C.size_t(newstate.Index))
  23. C.clua_initstate(L)
  24. return newstate
  25. }
  26. func (L *State) addFreeIndex(i uint) {
  27. freelen := len(L.freeIndices)
  28. //reallocate if necessary
  29. if freelen+1 > cap(L.freeIndices) {
  30. newSlice := make([]uint, freelen, cap(L.freeIndices)*2)
  31. copy(newSlice, L.freeIndices)
  32. L.freeIndices = newSlice
  33. }
  34. //reslice
  35. L.freeIndices = L.freeIndices[0 : freelen+1]
  36. L.freeIndices[freelen] = i
  37. }
  38. func (L *State) getFreeIndex() (index uint, ok bool) {
  39. freelen := len(L.freeIndices)
  40. //if there exist entries in the freelist
  41. if freelen > 0 {
  42. i := L.freeIndices[freelen-1] //get index
  43. //fmt.Printf("Free indices before: %v\n", L.freeIndices)
  44. L.freeIndices = L.freeIndices[0 : freelen-1] //'pop' index from list
  45. //fmt.Printf("Free indices after: %v\n", L.freeIndices)
  46. return i, true
  47. }
  48. return 0, false
  49. }
  50. //returns the registered function id
  51. func (L *State) register(f interface{}) uint {
  52. //fmt.Printf("Registering %v\n")
  53. index, ok := L.getFreeIndex()
  54. //fmt.Printf("\tfreeindex: index = %v, ok = %v\n", index, ok)
  55. //if not ok, then we need to add new index by extending the slice
  56. if !ok {
  57. index = uint(len(L.registry))
  58. //reallocate backing array if necessary
  59. if index+1 > uint(cap(L.registry)) {
  60. newcap := cap(L.registry) * 2
  61. if index+1 > uint(newcap) {
  62. newcap = int(index + 1)
  63. }
  64. newSlice := make([]interface{}, index, newcap)
  65. copy(newSlice, L.registry)
  66. L.registry = newSlice
  67. }
  68. //reslice
  69. L.registry = L.registry[0 : index+1]
  70. }
  71. //fmt.Printf("\tregistering %d %v\n", index, f)
  72. L.registry[index] = f
  73. return index
  74. }
  75. func (L *State) unregister(fid uint) {
  76. //fmt.Printf("Unregistering %d (len: %d, value: %v)\n", fid, len(L.registry), L.registry[fid])
  77. if (fid < uint(len(L.registry))) && (L.registry[fid] != nil) {
  78. L.registry[fid] = nil
  79. L.addFreeIndex(fid)
  80. }
  81. }
  82. // Like lua_pushcfunction pushes onto the stack a go function as user data
  83. func (L *State) PushGoFunction(f LuaGoFunction) {
  84. fid := L.register(f)
  85. C.clua_pushgofunction(L.s, C.uint(fid))
  86. }
  87. // PushGoClosure pushes a lua.LuaGoFunction to the stack wrapped in a Closure.
  88. // this permits the go function to reflect lua type 'function' when checking with type()
  89. // this implements behaviour akin to lua_pushcfunction() in lua C API.
  90. func (L *State) PushGoClosure(f LuaGoFunction) {
  91. L.PushGoFunction(f) // leaves Go function userdata on stack
  92. C.clua_pushcallback(L.s) // wraps the userdata object with a closure making it into a function
  93. }
  94. // Sets a metamethod to execute a go function
  95. //
  96. // The code:
  97. //
  98. // L.LGetMetaTable(tableName)
  99. // L.SetMetaMethod(methodName, function)
  100. //
  101. // is the logical equivalent of:
  102. //
  103. // L.LGetMetaTable(tableName)
  104. // L.PushGoFunction(function)
  105. // L.SetField(-2, methodName)
  106. //
  107. // except this wouldn't work because pushing a go function results in user data not a cfunction
  108. func (L *State) SetMetaMethod(methodName string, f LuaGoFunction) {
  109. L.PushGoFunction(f) // leaves Go function userdata on stack
  110. C.clua_pushcallback(L.s) // wraps the userdata object with a closure making it into a function
  111. L.SetField(-2, methodName)
  112. }
  113. // Pushes a Go struct onto the stack as user data.
  114. //
  115. // The user data will be rigged so that lua code can access and change to public members of simple types directly
  116. func (L *State) PushGoStruct(iface interface{}) {
  117. iid := L.register(iface)
  118. C.clua_pushgostruct(L.s, C.uint(iid))
  119. }
  120. // Push a pointer onto the stack as user data.
  121. //
  122. // This function doesn't save a reference to the interface, it is the responsibility of the caller of this function to insure that the interface outlasts the lifetime of the lua object that this function creates.
  123. func (L *State) PushLightUserdata(ud *interface{}) {
  124. //push
  125. C.lua_pushlightuserdata(L.s, unsafe.Pointer(ud))
  126. }
  127. // Creates a new user data object of specified size and returns it
  128. func (L *State) NewUserdata(size uintptr) unsafe.Pointer {
  129. return unsafe.Pointer(C.lua_newuserdata(L.s, C.size_t(size)))
  130. }
  131. // Sets the AtPanic function, returns the old one
  132. //
  133. // BUG(everyone_involved): passing nil causes serious problems
  134. func (L *State) AtPanic(panicf LuaGoFunction) (oldpanicf LuaGoFunction) {
  135. fid := uint(0)
  136. if panicf != nil {
  137. fid = L.register(panicf)
  138. }
  139. oldres := interface{}(C.clua_atpanic(L.s, C.uint(fid)))
  140. switch i := oldres.(type) {
  141. case C.uint:
  142. f := L.registry[uint(i)].(LuaGoFunction)
  143. //free registry entry
  144. L.unregister(uint(i))
  145. return f
  146. case C.lua_CFunction:
  147. return func(L1 *State) int {
  148. return int(C.clua_callluacfunc(L1.s, i))
  149. }
  150. }
  151. //generally we only get here if the panicf got set to something like nil
  152. //potentially dangerous because we may silently fail
  153. return nil
  154. }
  155. func (L *State) callEx(nargs, nresults int, catch bool) (err error) {
  156. if catch {
  157. defer func() {
  158. if err2 := recover(); err2 != nil {
  159. if _, ok := err2.(error); ok {
  160. err = err2.(error)
  161. }
  162. return
  163. }
  164. }()
  165. }
  166. L.GetGlobal(C.GOLUA_DEFAULT_MSGHANDLER)
  167. // We must record where we put the error handler in the stack otherwise it will be impossible to remove after the pcall when nresults == LUA_MULTRET
  168. erridx := L.GetTop() - nargs - 1
  169. L.Insert(erridx)
  170. r := L.pcall(nargs, nresults, erridx)
  171. L.Remove(erridx)
  172. if r != 0 {
  173. err = &LuaError{r, L.ToString(-1), L.StackTrace()}
  174. if !catch {
  175. panic(err)
  176. }
  177. }
  178. return
  179. }
  180. // lua_call
  181. func (L *State) Call(nargs, nresults int) (err error) {
  182. return L.callEx(nargs, nresults, true)
  183. }
  184. // Like lua_call but panics on errors
  185. func (L *State) MustCall(nargs, nresults int) {
  186. L.callEx(nargs, nresults, false)
  187. }
  188. // lua_checkstack
  189. func (L *State) CheckStack(extra int) bool {
  190. return C.lua_checkstack(L.s, C.int(extra)) != 0
  191. }
  192. // lua_close
  193. func (L *State) Close() {
  194. C.lua_close(L.s)
  195. unregisterGoState(L)
  196. }
  197. // lua_concat
  198. func (L *State) Concat(n int) {
  199. C.lua_concat(L.s, C.int(n))
  200. }
  201. // lua_createtable
  202. func (L *State) CreateTable(narr int, nrec int) {
  203. C.lua_createtable(L.s, C.int(narr), C.int(nrec))
  204. }
  205. // lua_getfield
  206. func (L *State) GetField(index int, k string) {
  207. Ck := C.CString(k)
  208. defer C.free(unsafe.Pointer(Ck))
  209. C.lua_getfield(L.s, C.int(index), Ck)
  210. }
  211. // lua_getmetatable
  212. func (L *State) GetMetaTable(index int) bool {
  213. return C.lua_getmetatable(L.s, C.int(index)) != 0
  214. }
  215. // lua_gettable
  216. func (L *State) GetTable(index int) { C.lua_gettable(L.s, C.int(index)) }
  217. // lua_gettop
  218. func (L *State) GetTop() int { return int(C.lua_gettop(L.s)) }
  219. // Returns true if lua_type == LUA_TBOOLEAN
  220. func (L *State) IsBoolean(index int) bool {
  221. return LuaValType(C.lua_type(L.s, C.int(index))) == LUA_TBOOLEAN
  222. }
  223. // Returns true if the value at index is a LuaGoFunction
  224. func (L *State) IsGoFunction(index int) bool {
  225. return C.clua_isgofunction(L.s, C.int(index)) != 0
  226. }
  227. // Returns true if the value at index is user data pushed with PushGoStruct
  228. func (L *State) IsGoStruct(index int) bool {
  229. return C.clua_isgostruct(L.s, C.int(index)) != 0
  230. }
  231. // Returns true if the value at index is user data pushed with PushGoFunction
  232. func (L *State) IsFunction(index int) bool {
  233. return LuaValType(C.lua_type(L.s, C.int(index))) == LUA_TFUNCTION
  234. }
  235. // Returns true if the value at index is light user data
  236. func (L *State) IsLightUserdata(index int) bool {
  237. return LuaValType(C.lua_type(L.s, C.int(index))) == LUA_TLIGHTUSERDATA
  238. }
  239. // lua_isnil
  240. func (L *State) IsNil(index int) bool { return LuaValType(C.lua_type(L.s, C.int(index))) == LUA_TNIL }
  241. // lua_isnone
  242. func (L *State) IsNone(index int) bool { return LuaValType(C.lua_type(L.s, C.int(index))) == LUA_TNONE }
  243. // lua_isnoneornil
  244. func (L *State) IsNoneOrNil(index int) bool { return int(C.lua_type(L.s, C.int(index))) <= 0 }
  245. // lua_isnumber
  246. func (L *State) IsNumber(index int) bool { return C.lua_isnumber(L.s, C.int(index)) == 1 }
  247. // lua_isstring
  248. func (L *State) IsString(index int) bool { return C.lua_isstring(L.s, C.int(index)) == 1 }
  249. // lua_istable
  250. func (L *State) IsTable(index int) bool {
  251. return LuaValType(C.lua_type(L.s, C.int(index))) == LUA_TTABLE
  252. }
  253. // lua_isthread
  254. func (L *State) IsThread(index int) bool {
  255. return LuaValType(C.lua_type(L.s, C.int(index))) == LUA_TTHREAD
  256. }
  257. // lua_isuserdata
  258. func (L *State) IsUserdata(index int) bool { return C.lua_isuserdata(L.s, C.int(index)) == 1 }
  259. // Creates a new lua interpreter state with the given allocation function
  260. func NewStateAlloc(f Alloc) *State {
  261. ls := C.clua_newstate(unsafe.Pointer(&f))
  262. L := newState(ls)
  263. L.allocfn = &f
  264. return L
  265. }
  266. // lua_newtable
  267. func (L *State) NewTable() {
  268. C.lua_createtable(L.s, 0, 0)
  269. }
  270. // lua_newthread
  271. func (L *State) NewThread() *State {
  272. //TODO: call newState with result from C.lua_newthread and return it
  273. //TODO: should have same lists as parent
  274. // but may complicate gc
  275. s := C.lua_newthread(L.s)
  276. return &State{s, 0, nil, nil, nil, nil}
  277. }
  278. // lua_next
  279. func (L *State) Next(index int) int {
  280. return int(C.lua_next(L.s, C.int(index)))
  281. }
  282. // lua_objlen
  283. // lua_pop
  284. func (L *State) Pop(n int) {
  285. //Why is this implemented this way? I don't get it...
  286. //C.lua_pop(L.s, C.int(n));
  287. C.lua_settop(L.s, C.int(-n-1))
  288. }
  289. // lua_pushboolean
  290. func (L *State) PushBoolean(b bool) {
  291. var bint int
  292. if b {
  293. bint = 1
  294. } else {
  295. bint = 0
  296. }
  297. C.lua_pushboolean(L.s, C.int(bint))
  298. }
  299. // lua_pushstring
  300. func (L *State) PushString(str string) {
  301. Cstr := C.CString(str)
  302. defer C.free(unsafe.Pointer(Cstr))
  303. C.lua_pushlstring(L.s, Cstr, C.size_t(len(str)))
  304. }
  305. func (L *State) PushBytes(b []byte) {
  306. C.lua_pushlstring(L.s, (*C.char)(unsafe.Pointer(&b[0])), C.size_t(len(b)))
  307. }
  308. // lua_pushinteger
  309. func (L *State) PushInteger(n int64) {
  310. C.lua_pushinteger(L.s, C.lua_Integer(n))
  311. }
  312. // lua_pushnil
  313. func (L *State) PushNil() {
  314. C.lua_pushnil(L.s)
  315. }
  316. // lua_pushnumber
  317. func (L *State) PushNumber(n float64) {
  318. C.lua_pushnumber(L.s, C.lua_Number(n))
  319. }
  320. // lua_pushthread
  321. func (L *State) PushThread() (isMain bool) {
  322. return C.lua_pushthread(L.s) != 0
  323. }
  324. // lua_pushvalue
  325. func (L *State) PushValue(index int) {
  326. C.lua_pushvalue(L.s, C.int(index))
  327. }
  328. // lua_rawequal
  329. func (L *State) RawEqual(index1 int, index2 int) bool {
  330. return C.lua_rawequal(L.s, C.int(index1), C.int(index2)) != 0
  331. }
  332. // lua_rawget
  333. func (L *State) RawGet(index int) {
  334. C.lua_rawget(L.s, C.int(index))
  335. }
  336. // lua_rawset
  337. func (L *State) RawSet(index int) {
  338. C.lua_rawset(L.s, C.int(index))
  339. }
  340. // Registers a Go function as a global variable
  341. func (L *State) Register(name string, f LuaGoFunction) {
  342. L.PushGoFunction(f)
  343. L.SetGlobal(name)
  344. }
  345. // lua_setallocf
  346. func (L *State) SetAllocf(f Alloc) {
  347. L.allocfn = &f
  348. C.clua_setallocf(L.s, unsafe.Pointer(L.allocfn))
  349. }
  350. // lua_setfield
  351. func (L *State) SetField(index int, k string) {
  352. Ck := C.CString(k)
  353. defer C.free(unsafe.Pointer(Ck))
  354. C.lua_setfield(L.s, C.int(index), Ck)
  355. }
  356. // lua_setmetatable
  357. func (L *State) SetMetaTable(index int) {
  358. C.lua_setmetatable(L.s, C.int(index))
  359. }
  360. // lua_settable
  361. func (L *State) SetTable(index int) {
  362. C.lua_settable(L.s, C.int(index))
  363. }
  364. // lua_settop
  365. func (L *State) SetTop(index int) {
  366. C.lua_settop(L.s, C.int(index))
  367. }
  368. // lua_status
  369. func (L *State) Status() int {
  370. return int(C.lua_status(L.s))
  371. }
  372. // lua_toboolean
  373. func (L *State) ToBoolean(index int) bool {
  374. return C.lua_toboolean(L.s, C.int(index)) != 0
  375. }
  376. // Returns the value at index as a Go function (it must be something pushed with PushGoFunction)
  377. func (L *State) ToGoFunction(index int) (f LuaGoFunction) {
  378. if !L.IsGoFunction(index) {
  379. return nil
  380. }
  381. fid := C.clua_togofunction(L.s, C.int(index))
  382. if fid < 0 {
  383. return nil
  384. }
  385. return L.registry[fid].(LuaGoFunction)
  386. }
  387. // Returns the value at index as a Go Struct (it must be something pushed with PushGoStruct)
  388. func (L *State) ToGoStruct(index int) (f interface{}) {
  389. if !L.IsGoStruct(index) {
  390. return nil
  391. }
  392. fid := C.clua_togostruct(L.s, C.int(index))
  393. if fid < 0 {
  394. return nil
  395. }
  396. return L.registry[fid]
  397. }
  398. // lua_tostring
  399. func (L *State) ToString(index int) string {
  400. var size C.size_t
  401. r := C.lua_tolstring(L.s, C.int(index), &size)
  402. return C.GoStringN(r, C.int(size))
  403. }
  404. func (L *State) ToBytes(index int) []byte {
  405. var size C.size_t
  406. b := C.lua_tolstring(L.s, C.int(index), &size)
  407. return C.GoBytes(unsafe.Pointer(b), C.int(size))
  408. }
  409. // lua_topointer
  410. func (L *State) ToPointer(index int) uintptr {
  411. return uintptr(C.lua_topointer(L.s, C.int(index)))
  412. }
  413. // lua_tothread
  414. func (L *State) ToThread(index int) *State {
  415. //TODO: find a way to link lua_State* to existing *State, return that
  416. return &State{}
  417. }
  418. // lua_touserdata
  419. func (L *State) ToUserdata(index int) unsafe.Pointer {
  420. return unsafe.Pointer(C.lua_touserdata(L.s, C.int(index)))
  421. }
  422. // lua_type
  423. func (L *State) Type(index int) LuaValType {
  424. return LuaValType(C.lua_type(L.s, C.int(index)))
  425. }
  426. // lua_typename
  427. func (L *State) Typename(tp int) string {
  428. return C.GoString(C.lua_typename(L.s, C.int(tp)))
  429. }
  430. // lua_xmove
  431. func XMove(from *State, to *State, n int) {
  432. C.lua_xmove(from.s, to.s, C.int(n))
  433. }
  434. // Restricted library opens
  435. // Calls luaopen_base
  436. func (L *State) OpenBase() {
  437. C.clua_openbase(L.s)
  438. }
  439. // Calls luaopen_io
  440. func (L *State) OpenIO() {
  441. C.clua_openio(L.s)
  442. }
  443. // Calls luaopen_math
  444. func (L *State) OpenMath() {
  445. C.clua_openmath(L.s)
  446. }
  447. // Calls luaopen_package
  448. func (L *State) OpenPackage() {
  449. C.clua_openpackage(L.s)
  450. }
  451. // Calls luaopen_string
  452. func (L *State) OpenString() {
  453. C.clua_openstring(L.s)
  454. }
  455. // Calls luaopen_table
  456. func (L *State) OpenTable() {
  457. C.clua_opentable(L.s)
  458. }
  459. // Calls luaopen_os
  460. func (L *State) OpenOS() {
  461. C.clua_openos(L.s)
  462. }
  463. // Sets the lua hook (lua_sethook).
  464. // This and SetExecutionLimit are mutual exclusive
  465. func (L *State) SetHook(f HookFunction, instrNumber int) {
  466. L.hookFn = f
  467. C.clua_sethook(L.s, C.int(instrNumber))
  468. }
  469. // Sets the maximum number of operations to execute at instrNumber, after this the execution ends
  470. // This and SetHook are mutual exclusive
  471. func (L *State) SetExecutionLimit(instrNumber int) {
  472. L.SetHook(func(l *State) {
  473. l.RaiseError(ExecutionQuantumExceeded)
  474. }, instrNumber)
  475. }
  476. // Returns the current stack trace
  477. func (L *State) StackTrace() []LuaStackEntry {
  478. r := []LuaStackEntry{}
  479. var d C.lua_Debug
  480. Sln := C.CString("Sln")
  481. defer C.free(unsafe.Pointer(Sln))
  482. for depth := 0; C.lua_getstack(L.s, C.int(depth), &d) > 0; depth++ {
  483. C.lua_getinfo(L.s, Sln, &d)
  484. ssb := make([]byte, C.LUA_IDSIZE)
  485. for i := 0; i < C.LUA_IDSIZE; i++ {
  486. ssb[i] = byte(d.short_src[i])
  487. if ssb[i] == 0 {
  488. ssb = ssb[:i]
  489. break
  490. }
  491. }
  492. ss := string(ssb)
  493. r = append(r, LuaStackEntry{C.GoString(d.name), C.GoString(d.source), ss, int(d.currentline)})
  494. }
  495. return r
  496. }
  497. func (L *State) RaiseError(msg string) {
  498. st := L.StackTrace()
  499. prefix := ""
  500. if len(st) >= 2 {
  501. prefix = fmt.Sprintf("%s:%d: ", st[1].ShortSource, st[1].CurrentLine)
  502. }
  503. panic(&LuaError{0, prefix + msg, st})
  504. }
  505. func (L *State) NewError(msg string) *LuaError {
  506. return &LuaError{0, msg, L.StackTrace()}
  507. }
  508. func (L *State) GetState() *C.lua_State {
  509. return L.s
  510. }