baselib.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. package lua
  2. import (
  3. "fmt"
  4. "io"
  5. "os"
  6. "runtime"
  7. "strconv"
  8. "strings"
  9. )
  10. /* basic functions {{{ */
  11. func OpenBase(L *LState) int {
  12. global := L.Get(GlobalsIndex).(*LTable)
  13. L.SetGlobal("_G", global)
  14. L.SetGlobal("_VERSION", LString(PackageName+" "+PackageVersion))
  15. basemod := L.RegisterModule("_G", baseFuncs)
  16. global.RawSetString("ipairs", L.NewClosure(baseIpairs, L.NewFunction(ipairsaux)))
  17. global.RawSetString("pairs", L.NewClosure(basePairs, L.NewFunction(pairsaux)))
  18. L.Push(basemod)
  19. return 1
  20. }
  21. var baseFuncs = map[string]LGFunction{
  22. "assert": baseAssert,
  23. "collectgarbage": baseCollectGarbage,
  24. "dofile": baseDoFile,
  25. "error": baseError,
  26. "getfenv": baseGetFEnv,
  27. "getmetatable": baseGetMetatable,
  28. "load": baseLoad,
  29. "loadfile": baseLoadFile,
  30. "loadstring": baseLoadString,
  31. "next": baseNext,
  32. "pcall": basePCall,
  33. "print": basePrint,
  34. "rawequal": baseRawEqual,
  35. "rawget": baseRawGet,
  36. "rawset": baseRawSet,
  37. "select": baseSelect,
  38. "_printregs": base_PrintRegs,
  39. "setfenv": baseSetFEnv,
  40. "setmetatable": baseSetMetatable,
  41. "tonumber": baseToNumber,
  42. "tostring": baseToString,
  43. "type": baseType,
  44. "unpack": baseUnpack,
  45. "xpcall": baseXPCall,
  46. // loadlib
  47. "module": loModule,
  48. "require": loRequire,
  49. }
  50. func baseAssert(L *LState) int {
  51. if !L.ToBool(1) {
  52. L.RaiseError(L.OptString(2, "assertion failed!"))
  53. return 0
  54. }
  55. return L.GetTop()
  56. }
  57. func baseCollectGarbage(L *LState) int {
  58. runtime.GC()
  59. return 0
  60. }
  61. func baseDoFile(L *LState) int {
  62. src := L.ToString(1)
  63. top := L.GetTop()
  64. fn, err := L.LoadFile(src)
  65. if err != nil {
  66. L.Push(LString(err.Error()))
  67. L.Panic(L)
  68. }
  69. L.Push(fn)
  70. L.Call(0, MultRet)
  71. return L.GetTop() - top
  72. }
  73. func baseError(L *LState) int {
  74. obj := L.CheckAny(1)
  75. level := L.OptInt(2, 1)
  76. L.Error(obj, level)
  77. return 0
  78. }
  79. func baseGetFEnv(L *LState) int {
  80. var value LValue
  81. if L.GetTop() == 0 {
  82. value = LNumber(1)
  83. } else {
  84. value = L.Get(1)
  85. }
  86. if fn, ok := value.(*LFunction); ok {
  87. if !fn.IsG {
  88. L.Push(fn.Env)
  89. } else {
  90. L.Push(L.G.Global)
  91. }
  92. return 1
  93. }
  94. if number, ok := value.(LNumber); ok {
  95. level := int(float64(number))
  96. if level <= 0 {
  97. L.Push(L.Env)
  98. } else {
  99. cf := L.currentFrame
  100. for i := 0; i < level && cf != nil; i++ {
  101. cf = cf.Parent
  102. }
  103. if cf == nil || cf.Fn.IsG {
  104. L.Push(L.G.Global)
  105. } else {
  106. L.Push(cf.Fn.Env)
  107. }
  108. }
  109. return 1
  110. }
  111. L.Push(L.G.Global)
  112. return 1
  113. }
  114. func baseGetMetatable(L *LState) int {
  115. L.Push(L.GetMetatable(L.CheckAny(1)))
  116. return 1
  117. }
  118. func ipairsaux(L *LState) int {
  119. tb := L.CheckTable(1)
  120. i := L.CheckInt(2)
  121. i++
  122. v := tb.RawGetInt(i)
  123. if v == LNil {
  124. return 0
  125. } else {
  126. L.Pop(1)
  127. L.Push(LNumber(i))
  128. L.Push(LNumber(i))
  129. L.Push(v)
  130. return 2
  131. }
  132. }
  133. func baseIpairs(L *LState) int {
  134. tb := L.CheckTable(1)
  135. L.Push(L.Get(UpvalueIndex(1)))
  136. L.Push(tb)
  137. L.Push(LNumber(0))
  138. return 3
  139. }
  140. func loadaux(L *LState, reader io.Reader, chunkname string) int {
  141. if fn, err := L.Load(reader, chunkname); err != nil {
  142. L.Push(LNil)
  143. L.Push(LString(err.Error()))
  144. return 2
  145. } else {
  146. L.Push(fn)
  147. return 1
  148. }
  149. }
  150. func baseLoad(L *LState) int {
  151. fn := L.CheckFunction(1)
  152. chunkname := L.OptString(2, "?")
  153. top := L.GetTop()
  154. buf := []string{}
  155. for {
  156. L.SetTop(top)
  157. L.Push(fn)
  158. L.Call(0, 1)
  159. ret := L.reg.Pop()
  160. if ret == LNil {
  161. break
  162. } else if LVCanConvToString(ret) {
  163. str := ret.String()
  164. if len(str) > 0 {
  165. buf = append(buf, string(str))
  166. } else {
  167. break
  168. }
  169. } else {
  170. L.Push(LNil)
  171. L.Push(LString("reader function must return a string"))
  172. return 2
  173. }
  174. }
  175. return loadaux(L, strings.NewReader(strings.Join(buf, "")), chunkname)
  176. }
  177. func baseLoadFile(L *LState) int {
  178. var reader io.Reader
  179. var chunkname string
  180. var err error
  181. if L.GetTop() < 1 {
  182. reader = os.Stdin
  183. chunkname = "<stdin>"
  184. } else {
  185. chunkname = L.CheckString(1)
  186. reader, err = os.Open(chunkname)
  187. if err != nil {
  188. L.Push(LNil)
  189. L.Push(LString(fmt.Sprintf("can not open file: %v", chunkname)))
  190. return 2
  191. }
  192. defer reader.(*os.File).Close()
  193. }
  194. return loadaux(L, reader, chunkname)
  195. }
  196. func baseLoadString(L *LState) int {
  197. return loadaux(L, strings.NewReader(L.CheckString(1)), L.OptString(2, "<string>"))
  198. }
  199. func baseNext(L *LState) int {
  200. tb := L.CheckTable(1)
  201. index := LNil
  202. if L.GetTop() >= 2 {
  203. index = L.Get(2)
  204. }
  205. key, value := tb.Next(index)
  206. if key == LNil {
  207. L.Push(LNil)
  208. return 1
  209. }
  210. L.Push(key)
  211. L.Push(value)
  212. return 2
  213. }
  214. func pairsaux(L *LState) int {
  215. tb := L.CheckTable(1)
  216. key, value := tb.Next(L.Get(2))
  217. if key == LNil {
  218. return 0
  219. } else {
  220. L.Pop(1)
  221. L.Push(key)
  222. L.Push(key)
  223. L.Push(value)
  224. return 2
  225. }
  226. }
  227. func basePairs(L *LState) int {
  228. tb := L.CheckTable(1)
  229. L.Push(L.Get(UpvalueIndex(1)))
  230. L.Push(tb)
  231. L.Push(LNil)
  232. return 3
  233. }
  234. func basePCall(L *LState) int {
  235. L.CheckFunction(1)
  236. nargs := L.GetTop() - 1
  237. if err := L.PCall(nargs, MultRet, nil); err != nil {
  238. L.Push(LFalse)
  239. if aerr, ok := err.(*ApiError); ok {
  240. L.Push(aerr.Object)
  241. } else {
  242. L.Push(LString(err.Error()))
  243. }
  244. return 2
  245. } else {
  246. L.Insert(LTrue, 1)
  247. return L.GetTop()
  248. }
  249. }
  250. func basePrint(L *LState) int {
  251. top := L.GetTop()
  252. for i := 1; i <= top; i++ {
  253. fmt.Print(L.ToStringMeta(L.Get(i)).String())
  254. if i != top {
  255. fmt.Print("\t")
  256. }
  257. }
  258. fmt.Println("")
  259. return 0
  260. }
  261. func base_PrintRegs(L *LState) int {
  262. L.printReg()
  263. return 0
  264. }
  265. func baseRawEqual(L *LState) int {
  266. if L.CheckAny(1) == L.CheckAny(2) {
  267. L.Push(LTrue)
  268. } else {
  269. L.Push(LFalse)
  270. }
  271. return 1
  272. }
  273. func baseRawGet(L *LState) int {
  274. L.Push(L.RawGet(L.CheckTable(1), L.CheckAny(2)))
  275. return 1
  276. }
  277. func baseRawSet(L *LState) int {
  278. L.RawSet(L.CheckTable(1), L.CheckAny(2), L.CheckAny(3))
  279. return 0
  280. }
  281. func baseSelect(L *LState) int {
  282. L.CheckTypes(1, LTNumber, LTString)
  283. switch lv := L.Get(1).(type) {
  284. case LNumber:
  285. idx := int(lv)
  286. num := L.reg.Top() - L.indexToReg(int(lv)) - 1
  287. if idx < 0 {
  288. num++
  289. }
  290. return num
  291. case LString:
  292. if string(lv) != "#" {
  293. L.ArgError(1, "invalid string '"+string(lv)+"'")
  294. }
  295. L.Push(LNumber(L.GetTop() - 1))
  296. return 1
  297. }
  298. return 0
  299. }
  300. func baseSetFEnv(L *LState) int {
  301. var value LValue
  302. if L.GetTop() == 0 {
  303. value = LNumber(1)
  304. } else {
  305. value = L.Get(1)
  306. }
  307. env := L.CheckTable(2)
  308. if fn, ok := value.(*LFunction); ok {
  309. if fn.IsG {
  310. L.RaiseError("cannot change the environment of given object")
  311. } else {
  312. fn.Env = env
  313. L.Push(fn)
  314. return 1
  315. }
  316. }
  317. if number, ok := value.(LNumber); ok {
  318. level := int(float64(number))
  319. if level <= 0 {
  320. L.Env = env
  321. return 0
  322. }
  323. cf := L.currentFrame
  324. for i := 0; i < level && cf != nil; i++ {
  325. cf = cf.Parent
  326. }
  327. if cf == nil || cf.Fn.IsG {
  328. L.RaiseError("cannot change the environment of given object")
  329. } else {
  330. cf.Fn.Env = env
  331. L.Push(cf.Fn)
  332. return 1
  333. }
  334. }
  335. L.RaiseError("cannot change the environment of given object")
  336. return 0
  337. }
  338. func baseSetMetatable(L *LState) int {
  339. L.CheckTypes(2, LTNil, LTTable)
  340. obj := L.Get(1)
  341. if obj == LNil {
  342. L.RaiseError("cannot set metatable to a nil object.")
  343. }
  344. mt := L.Get(2)
  345. if m := L.metatable(obj, true); m != LNil {
  346. if tb, ok := m.(*LTable); ok && tb.RawGetString("__metatable") != LNil {
  347. L.RaiseError("cannot change a protected metatable")
  348. }
  349. }
  350. L.SetMetatable(obj, mt)
  351. L.SetTop(1)
  352. return 1
  353. }
  354. func baseToNumber(L *LState) int {
  355. base := L.OptInt(2, 10)
  356. noBase := L.Get(2) == LNil
  357. switch lv := L.CheckAny(1).(type) {
  358. case LNumber:
  359. L.Push(lv)
  360. case LString:
  361. str := strings.Trim(string(lv), " \n\t")
  362. if strings.Index(str, ".") > -1 {
  363. if v, err := strconv.ParseFloat(str, LNumberBit); err != nil {
  364. L.Push(LNil)
  365. } else {
  366. L.Push(LNumber(v))
  367. }
  368. } else {
  369. if noBase && strings.HasPrefix(strings.ToLower(str), "0x") {
  370. base, str = 16, str[2:] // Hex number
  371. }
  372. if v, err := strconv.ParseInt(str, base, LNumberBit); err != nil {
  373. L.Push(LNil)
  374. } else {
  375. L.Push(LNumber(v))
  376. }
  377. }
  378. default:
  379. L.Push(LNil)
  380. }
  381. return 1
  382. }
  383. func baseToString(L *LState) int {
  384. v1 := L.CheckAny(1)
  385. L.Push(L.ToStringMeta(v1))
  386. return 1
  387. }
  388. func baseType(L *LState) int {
  389. L.Push(LString(L.CheckAny(1).Type().String()))
  390. return 1
  391. }
  392. func baseUnpack(L *LState) int {
  393. tb := L.CheckTable(1)
  394. start := L.OptInt(2, 1)
  395. end := L.OptInt(3, tb.Len())
  396. for i := start; i <= end; i++ {
  397. L.Push(tb.RawGetInt(i))
  398. }
  399. ret := end - start + 1
  400. if ret < 0 {
  401. return 0
  402. }
  403. return ret
  404. }
  405. func baseXPCall(L *LState) int {
  406. fn := L.CheckFunction(1)
  407. errfunc := L.CheckFunction(2)
  408. top := L.GetTop()
  409. L.Push(fn)
  410. if err := L.PCall(0, MultRet, errfunc); err != nil {
  411. L.Push(LFalse)
  412. if aerr, ok := err.(*ApiError); ok {
  413. L.Push(aerr.Object)
  414. } else {
  415. L.Push(LString(err.Error()))
  416. }
  417. return 2
  418. } else {
  419. L.Insert(LTrue, top+1)
  420. return L.GetTop() - top
  421. }
  422. }
  423. /* }}} */
  424. /* load lib {{{ */
  425. func loModule(L *LState) int {
  426. name := L.CheckString(1)
  427. loaded := L.GetField(L.Get(RegistryIndex), "_LOADED")
  428. tb := L.GetField(loaded, name)
  429. if _, ok := tb.(*LTable); !ok {
  430. tb = L.FindTable(L.Get(GlobalsIndex).(*LTable), name, 1)
  431. if tb == LNil {
  432. L.RaiseError("name conflict for module: %v", name)
  433. }
  434. L.SetField(loaded, name, tb)
  435. }
  436. if L.GetField(tb, "_NAME") == LNil {
  437. L.SetField(tb, "_M", tb)
  438. L.SetField(tb, "_NAME", LString(name))
  439. names := strings.Split(name, ".")
  440. pname := ""
  441. if len(names) > 1 {
  442. pname = strings.Join(names[:len(names)-1], ".") + "."
  443. }
  444. L.SetField(tb, "_PACKAGE", LString(pname))
  445. }
  446. caller := L.currentFrame.Parent
  447. if caller == nil {
  448. L.RaiseError("no calling stack.")
  449. } else if caller.Fn.IsG {
  450. L.RaiseError("module() can not be called from GFunctions.")
  451. }
  452. L.SetFEnv(caller.Fn, tb)
  453. top := L.GetTop()
  454. for i := 2; i <= top; i++ {
  455. L.Push(L.Get(i))
  456. L.Push(tb)
  457. L.Call(1, 0)
  458. }
  459. L.Push(tb)
  460. return 1
  461. }
  462. var loopdetection = &LUserData{}
  463. func loRequire(L *LState) int {
  464. name := L.CheckString(1)
  465. loaded := L.GetField(L.Get(RegistryIndex), "_LOADED")
  466. lv := L.GetField(loaded, name)
  467. if LVAsBool(lv) {
  468. if lv == loopdetection {
  469. L.RaiseError("loop or previous error loading module: %s", name)
  470. }
  471. L.Push(lv)
  472. return 1
  473. }
  474. loaders, ok := L.GetField(L.Get(RegistryIndex), "_LOADERS").(*LTable)
  475. if !ok {
  476. L.RaiseError("package.loaders must be a table")
  477. }
  478. messages := []string{}
  479. var modasfunc LValue
  480. for i := 1; ; i++ {
  481. loader := L.RawGetInt(loaders, i)
  482. if loader == LNil {
  483. L.RaiseError("module %s not found:\n\t%s, ", name, strings.Join(messages, "\n\t"))
  484. }
  485. L.Push(loader)
  486. L.Push(LString(name))
  487. L.Call(1, 1)
  488. ret := L.reg.Pop()
  489. switch retv := ret.(type) {
  490. case *LFunction:
  491. modasfunc = retv
  492. goto loopbreak
  493. case LString:
  494. messages = append(messages, string(retv))
  495. }
  496. }
  497. loopbreak:
  498. L.SetField(loaded, name, loopdetection)
  499. L.Push(modasfunc)
  500. L.Push(LString(name))
  501. L.Call(1, 1)
  502. ret := L.reg.Pop()
  503. modv := L.GetField(loaded, name)
  504. if ret != LNil && modv == loopdetection {
  505. L.SetField(loaded, name, ret)
  506. L.Push(ret)
  507. } else if modv == loopdetection {
  508. L.SetField(loaded, name, LTrue)
  509. L.Push(LTrue)
  510. } else {
  511. L.Push(modv)
  512. }
  513. return 1
  514. }
  515. /* }}} */
  516. //