_vm.go 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. package lua
  2. import (
  3. "fmt"
  4. "math"
  5. "strings"
  6. )
  7. func mainLoop(L *LState, baseframe *callFrame) {
  8. var inst uint32
  9. var cf *callFrame
  10. if L.stack.IsEmpty() {
  11. return
  12. }
  13. L.currentFrame = L.stack.Last()
  14. if L.currentFrame.Fn.IsG {
  15. callGFunction(L, false)
  16. return
  17. }
  18. for {
  19. cf = L.currentFrame
  20. inst = cf.Fn.Proto.Code[cf.Pc]
  21. cf.Pc++
  22. if jumpTable[int(inst>>26)](L, inst, baseframe) == 1 {
  23. return
  24. }
  25. }
  26. }
  27. func mainLoopWithContext(L *LState, baseframe *callFrame) {
  28. var inst uint32
  29. var cf *callFrame
  30. if L.stack.IsEmpty() {
  31. return
  32. }
  33. L.currentFrame = L.stack.Last()
  34. if L.currentFrame.Fn.IsG {
  35. callGFunction(L, false)
  36. return
  37. }
  38. for {
  39. cf = L.currentFrame
  40. inst = cf.Fn.Proto.Code[cf.Pc]
  41. cf.Pc++
  42. select {
  43. case <-L.ctx.Done():
  44. L.RaiseError(L.ctx.Err().Error())
  45. return
  46. default:
  47. if jumpTable[int(inst>>26)](L, inst, baseframe) == 1 {
  48. return
  49. }
  50. }
  51. }
  52. }
  53. func copyReturnValues(L *LState, regv, start, n, b int) { // +inline-start
  54. if b == 1 {
  55. // +inline-call L.reg.FillNil regv n
  56. } else {
  57. // +inline-call L.reg.CopyRange regv start -1 n
  58. }
  59. } // +inline-end
  60. func switchToParentThread(L *LState, nargs int, haserror bool, kill bool) {
  61. parent := L.Parent
  62. if parent == nil {
  63. L.RaiseError("can not yield from outside of a coroutine")
  64. }
  65. L.G.CurrentThread = parent
  66. L.Parent = nil
  67. if !L.wrapped {
  68. if haserror {
  69. parent.Push(LFalse)
  70. } else {
  71. parent.Push(LTrue)
  72. }
  73. }
  74. L.XMoveTo(parent, nargs)
  75. L.stack.Pop()
  76. offset := L.currentFrame.LocalBase - L.currentFrame.ReturnBase
  77. L.currentFrame = L.stack.Last()
  78. L.reg.SetTop(L.reg.Top() - offset) // remove 'yield' function(including tailcalled functions)
  79. if kill {
  80. L.kill()
  81. }
  82. }
  83. func callGFunction(L *LState, tailcall bool) bool {
  84. frame := L.currentFrame
  85. gfnret := frame.Fn.GFunction(L)
  86. if tailcall {
  87. L.stack.Remove(L.stack.Sp() - 2) // remove caller lua function frame
  88. L.currentFrame = L.stack.Last()
  89. }
  90. if gfnret < 0 {
  91. switchToParentThread(L, L.GetTop(), false, false)
  92. return true
  93. }
  94. wantret := frame.NRet
  95. if wantret == MultRet {
  96. wantret = gfnret
  97. }
  98. if tailcall && L.Parent != nil && L.stack.Sp() == 1 {
  99. switchToParentThread(L, wantret, false, true)
  100. return true
  101. }
  102. // +inline-call L.reg.CopyRange frame.ReturnBase L.reg.Top()-gfnret -1 wantret
  103. L.stack.Pop()
  104. L.currentFrame = L.stack.Last()
  105. return false
  106. }
  107. func threadRun(L *LState) {
  108. if L.stack.IsEmpty() {
  109. return
  110. }
  111. defer func() {
  112. if rcv := recover(); rcv != nil {
  113. var lv LValue
  114. if v, ok := rcv.(*ApiError); ok {
  115. lv = v.Object
  116. } else {
  117. lv = LString(fmt.Sprint(rcv))
  118. }
  119. if parent := L.Parent; parent != nil {
  120. if L.wrapped {
  121. L.Push(lv)
  122. parent.Panic(L)
  123. } else {
  124. L.SetTop(0)
  125. L.Push(lv)
  126. switchToParentThread(L, 1, true, true)
  127. }
  128. } else {
  129. panic(rcv)
  130. }
  131. }
  132. }()
  133. L.mainLoop(L, nil)
  134. }
  135. type instFunc func(*LState, uint32, *callFrame) int
  136. var jumpTable [opCodeMax + 1]instFunc
  137. func init() {
  138. jumpTable = [opCodeMax + 1]instFunc{
  139. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_MOVE
  140. reg := L.reg
  141. cf := L.currentFrame
  142. lbase := cf.LocalBase
  143. A := int(inst>>18) & 0xff //GETA
  144. RA := lbase + A
  145. B := int(inst & 0x1ff) //GETB
  146. reg.Set(RA, reg.Get(lbase+B))
  147. return 0
  148. },
  149. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_MOVEN
  150. reg := L.reg
  151. cf := L.currentFrame
  152. lbase := cf.LocalBase
  153. A := int(inst>>18) & 0xff //GETA
  154. B := int(inst & 0x1ff) //GETB
  155. C := int(inst>>9) & 0x1ff //GETC
  156. reg.Set(lbase+A, reg.Get(lbase+B))
  157. code := cf.Fn.Proto.Code
  158. pc := cf.Pc
  159. for i := 0; i < C; i++ {
  160. inst = code[pc]
  161. pc++
  162. A = int(inst>>18) & 0xff //GETA
  163. B = int(inst & 0x1ff) //GETB
  164. reg.Set(lbase+A, reg.Get(lbase+B))
  165. }
  166. cf.Pc = pc
  167. return 0
  168. },
  169. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADK
  170. reg := L.reg
  171. cf := L.currentFrame
  172. lbase := cf.LocalBase
  173. A := int(inst>>18) & 0xff //GETA
  174. RA := lbase + A
  175. Bx := int(inst & 0x3ffff) //GETBX
  176. reg.Set(RA, cf.Fn.Proto.Constants[Bx])
  177. return 0
  178. },
  179. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADBOOL
  180. reg := L.reg
  181. cf := L.currentFrame
  182. lbase := cf.LocalBase
  183. A := int(inst>>18) & 0xff //GETA
  184. RA := lbase + A
  185. B := int(inst & 0x1ff) //GETB
  186. C := int(inst>>9) & 0x1ff //GETC
  187. if B != 0 {
  188. reg.Set(RA, LTrue)
  189. } else {
  190. reg.Set(RA, LFalse)
  191. }
  192. if C != 0 {
  193. cf.Pc++
  194. }
  195. return 0
  196. },
  197. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LOADNIL
  198. reg := L.reg
  199. cf := L.currentFrame
  200. lbase := cf.LocalBase
  201. A := int(inst>>18) & 0xff //GETA
  202. RA := lbase + A
  203. B := int(inst & 0x1ff) //GETB
  204. for i := RA; i <= lbase+B; i++ {
  205. reg.Set(i, LNil)
  206. }
  207. return 0
  208. },
  209. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETUPVAL
  210. reg := L.reg
  211. cf := L.currentFrame
  212. lbase := cf.LocalBase
  213. A := int(inst>>18) & 0xff //GETA
  214. RA := lbase + A
  215. B := int(inst & 0x1ff) //GETB
  216. reg.Set(RA, cf.Fn.Upvalues[B].Value())
  217. return 0
  218. },
  219. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETGLOBAL
  220. reg := L.reg
  221. cf := L.currentFrame
  222. lbase := cf.LocalBase
  223. A := int(inst>>18) & 0xff //GETA
  224. RA := lbase + A
  225. Bx := int(inst & 0x3ffff) //GETBX
  226. //reg.Set(RA, L.getField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx]))
  227. reg.Set(RA, L.getFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx]))
  228. return 0
  229. },
  230. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLE
  231. reg := L.reg
  232. cf := L.currentFrame
  233. lbase := cf.LocalBase
  234. A := int(inst>>18) & 0xff //GETA
  235. RA := lbase + A
  236. B := int(inst & 0x1ff) //GETB
  237. C := int(inst>>9) & 0x1ff //GETC
  238. reg.Set(RA, L.getField(reg.Get(lbase+B), L.rkValue(C)))
  239. return 0
  240. },
  241. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_GETTABLEKS
  242. reg := L.reg
  243. cf := L.currentFrame
  244. lbase := cf.LocalBase
  245. A := int(inst>>18) & 0xff //GETA
  246. RA := lbase + A
  247. B := int(inst & 0x1ff) //GETB
  248. C := int(inst>>9) & 0x1ff //GETC
  249. reg.Set(RA, L.getFieldString(reg.Get(lbase+B), L.rkString(C)))
  250. return 0
  251. },
  252. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETGLOBAL
  253. reg := L.reg
  254. cf := L.currentFrame
  255. lbase := cf.LocalBase
  256. A := int(inst>>18) & 0xff //GETA
  257. RA := lbase + A
  258. Bx := int(inst & 0x3ffff) //GETBX
  259. //L.setField(cf.Fn.Env, cf.Fn.Proto.Constants[Bx], reg.Get(RA))
  260. L.setFieldString(cf.Fn.Env, cf.Fn.Proto.stringConstants[Bx], reg.Get(RA))
  261. return 0
  262. },
  263. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETUPVAL
  264. reg := L.reg
  265. cf := L.currentFrame
  266. lbase := cf.LocalBase
  267. A := int(inst>>18) & 0xff //GETA
  268. RA := lbase + A
  269. B := int(inst & 0x1ff) //GETB
  270. cf.Fn.Upvalues[B].SetValue(reg.Get(RA))
  271. return 0
  272. },
  273. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETTABLE
  274. reg := L.reg
  275. cf := L.currentFrame
  276. lbase := cf.LocalBase
  277. A := int(inst>>18) & 0xff //GETA
  278. RA := lbase + A
  279. B := int(inst & 0x1ff) //GETB
  280. C := int(inst>>9) & 0x1ff //GETC
  281. L.setField(reg.Get(RA), L.rkValue(B), L.rkValue(C))
  282. return 0
  283. },
  284. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETTABLEKS
  285. reg := L.reg
  286. cf := L.currentFrame
  287. lbase := cf.LocalBase
  288. A := int(inst>>18) & 0xff //GETA
  289. RA := lbase + A
  290. B := int(inst & 0x1ff) //GETB
  291. C := int(inst>>9) & 0x1ff //GETC
  292. L.setFieldString(reg.Get(RA), L.rkString(B), L.rkValue(C))
  293. return 0
  294. },
  295. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NEWTABLE
  296. reg := L.reg
  297. cf := L.currentFrame
  298. lbase := cf.LocalBase
  299. A := int(inst>>18) & 0xff //GETA
  300. RA := lbase + A
  301. B := int(inst & 0x1ff) //GETB
  302. C := int(inst>>9) & 0x1ff //GETC
  303. reg.Set(RA, newLTable(B, C))
  304. return 0
  305. },
  306. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SELF
  307. reg := L.reg
  308. cf := L.currentFrame
  309. lbase := cf.LocalBase
  310. A := int(inst>>18) & 0xff //GETA
  311. RA := lbase + A
  312. B := int(inst & 0x1ff) //GETB
  313. C := int(inst>>9) & 0x1ff //GETC
  314. selfobj := reg.Get(lbase + B)
  315. reg.Set(RA, L.getFieldString(selfobj, L.rkString(C)))
  316. reg.Set(RA+1, selfobj)
  317. return 0
  318. },
  319. opArith, // OP_ADD
  320. opArith, // OP_SUB
  321. opArith, // OP_MUL
  322. opArith, // OP_DIV
  323. opArith, // OP_MOD
  324. opArith, // OP_POW
  325. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_UNM
  326. reg := L.reg
  327. cf := L.currentFrame
  328. lbase := cf.LocalBase
  329. A := int(inst>>18) & 0xff //GETA
  330. RA := lbase + A
  331. B := int(inst & 0x1ff) //GETB
  332. unaryv := L.rkValue(B)
  333. if nm, ok := unaryv.(LNumber); ok {
  334. reg.SetNumber(RA, -nm)
  335. } else {
  336. op := L.metaOp1(unaryv, "__unm")
  337. if op.Type() == LTFunction {
  338. reg.Push(op)
  339. reg.Push(unaryv)
  340. L.Call(1, 1)
  341. reg.Set(RA, reg.Pop())
  342. } else if str, ok1 := unaryv.(LString); ok1 {
  343. if num, err := parseNumber(string(str)); err == nil {
  344. reg.Set(RA, -num)
  345. } else {
  346. L.RaiseError("__unm undefined")
  347. }
  348. } else {
  349. L.RaiseError("__unm undefined")
  350. }
  351. }
  352. return 0
  353. },
  354. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOT
  355. reg := L.reg
  356. cf := L.currentFrame
  357. lbase := cf.LocalBase
  358. A := int(inst>>18) & 0xff //GETA
  359. RA := lbase + A
  360. B := int(inst & 0x1ff) //GETB
  361. if LVIsFalse(reg.Get(lbase + B)) {
  362. reg.Set(RA, LTrue)
  363. } else {
  364. reg.Set(RA, LFalse)
  365. }
  366. return 0
  367. },
  368. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LEN
  369. reg := L.reg
  370. cf := L.currentFrame
  371. lbase := cf.LocalBase
  372. A := int(inst>>18) & 0xff //GETA
  373. RA := lbase + A
  374. B := int(inst & 0x1ff) //GETB
  375. switch lv := L.rkValue(B).(type) {
  376. case LString:
  377. reg.SetNumber(RA, LNumber(len(lv)))
  378. default:
  379. op := L.metaOp1(lv, "__len")
  380. if op.Type() == LTFunction {
  381. reg.Push(op)
  382. reg.Push(lv)
  383. L.Call(1, 1)
  384. reg.Set(RA, reg.Pop())
  385. } else if lv.Type() == LTTable {
  386. reg.SetNumber(RA, LNumber(lv.(*LTable).Len()))
  387. } else {
  388. L.RaiseError("__len undefined")
  389. }
  390. }
  391. return 0
  392. },
  393. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CONCAT
  394. reg := L.reg
  395. cf := L.currentFrame
  396. lbase := cf.LocalBase
  397. A := int(inst>>18) & 0xff //GETA
  398. RA := lbase + A
  399. B := int(inst & 0x1ff) //GETB
  400. C := int(inst>>9) & 0x1ff //GETC
  401. RC := lbase + C
  402. RB := lbase + B
  403. reg.Set(RA, stringConcat(L, RC-RB+1, RC))
  404. return 0
  405. },
  406. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_JMP
  407. cf := L.currentFrame
  408. Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
  409. cf.Pc += Sbx
  410. return 0
  411. },
  412. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_EQ
  413. cf := L.currentFrame
  414. A := int(inst>>18) & 0xff //GETA
  415. B := int(inst & 0x1ff) //GETB
  416. C := int(inst>>9) & 0x1ff //GETC
  417. ret := equals(L, L.rkValue(B), L.rkValue(C), false)
  418. v := 1
  419. if ret {
  420. v = 0
  421. }
  422. if v == A {
  423. cf.Pc++
  424. }
  425. return 0
  426. },
  427. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LT
  428. cf := L.currentFrame
  429. A := int(inst>>18) & 0xff //GETA
  430. B := int(inst & 0x1ff) //GETB
  431. C := int(inst>>9) & 0x1ff //GETC
  432. ret := lessThan(L, L.rkValue(B), L.rkValue(C))
  433. v := 1
  434. if ret {
  435. v = 0
  436. }
  437. if v == A {
  438. cf.Pc++
  439. }
  440. return 0
  441. },
  442. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_LE
  443. cf := L.currentFrame
  444. A := int(inst>>18) & 0xff //GETA
  445. B := int(inst & 0x1ff) //GETB
  446. C := int(inst>>9) & 0x1ff //GETC
  447. lhs := L.rkValue(B)
  448. rhs := L.rkValue(C)
  449. ret := false
  450. if v1, ok1 := lhs.assertFloat64(); ok1 {
  451. if v2, ok2 := rhs.assertFloat64(); ok2 {
  452. ret = v1 <= v2
  453. } else {
  454. L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  455. }
  456. } else {
  457. if lhs.Type() != rhs.Type() {
  458. L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  459. }
  460. switch lhs.Type() {
  461. case LTString:
  462. ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) <= 0
  463. default:
  464. switch objectRational(L, lhs, rhs, "__le") {
  465. case 1:
  466. ret = true
  467. case 0:
  468. ret = false
  469. default:
  470. ret = !objectRationalWithError(L, rhs, lhs, "__lt")
  471. }
  472. }
  473. }
  474. v := 1
  475. if ret {
  476. v = 0
  477. }
  478. if v == A {
  479. cf.Pc++
  480. }
  481. return 0
  482. },
  483. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TEST
  484. reg := L.reg
  485. cf := L.currentFrame
  486. lbase := cf.LocalBase
  487. A := int(inst>>18) & 0xff //GETA
  488. RA := lbase + A
  489. C := int(inst>>9) & 0x1ff //GETC
  490. if LVAsBool(reg.Get(RA)) == (C == 0) {
  491. cf.Pc++
  492. }
  493. return 0
  494. },
  495. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TESTSET
  496. reg := L.reg
  497. cf := L.currentFrame
  498. lbase := cf.LocalBase
  499. A := int(inst>>18) & 0xff //GETA
  500. RA := lbase + A
  501. B := int(inst & 0x1ff) //GETB
  502. C := int(inst>>9) & 0x1ff //GETC
  503. if value := reg.Get(lbase + B); LVAsBool(value) != (C == 0) {
  504. reg.Set(RA, value)
  505. } else {
  506. cf.Pc++
  507. }
  508. return 0
  509. },
  510. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CALL
  511. reg := L.reg
  512. cf := L.currentFrame
  513. lbase := cf.LocalBase
  514. A := int(inst>>18) & 0xff //GETA
  515. RA := lbase + A
  516. B := int(inst & 0x1ff) //GETB
  517. C := int(inst>>9) & 0x1ff //GETC
  518. nargs := B - 1
  519. if B == 0 {
  520. nargs = reg.Top() - (RA + 1)
  521. }
  522. lv := reg.Get(RA)
  523. nret := C - 1
  524. var callable *LFunction
  525. var meta bool
  526. if fn, ok := lv.assertFunction(); ok {
  527. callable = fn
  528. meta = false
  529. } else {
  530. callable, meta = L.metaCall(lv)
  531. }
  532. // +inline-call L.pushCallFrame callFrame{Fn:callable,Pc:0,Base:RA,LocalBase:RA+1,ReturnBase:RA,NArgs:nargs,NRet:nret,Parent:cf,TailCall:0} lv meta
  533. if callable.IsG && callGFunction(L, false) {
  534. return 1
  535. }
  536. return 0
  537. },
  538. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TAILCALL
  539. reg := L.reg
  540. cf := L.currentFrame
  541. lbase := cf.LocalBase
  542. A := int(inst>>18) & 0xff //GETA
  543. RA := lbase + A
  544. B := int(inst & 0x1ff) //GETB
  545. nargs := B - 1
  546. if B == 0 {
  547. nargs = reg.Top() - (RA + 1)
  548. }
  549. lv := reg.Get(RA)
  550. var callable *LFunction
  551. var meta bool
  552. if fn, ok := lv.assertFunction(); ok {
  553. callable = fn
  554. meta = false
  555. } else {
  556. callable, meta = L.metaCall(lv)
  557. }
  558. if callable == nil {
  559. L.RaiseError("attempt to call a non-function object")
  560. }
  561. // +inline-call L.closeUpvalues lbase
  562. if callable.IsG {
  563. luaframe := cf
  564. L.pushCallFrame(callFrame{
  565. Fn: callable,
  566. Pc: 0,
  567. Base: RA,
  568. LocalBase: RA + 1,
  569. ReturnBase: cf.ReturnBase,
  570. NArgs: nargs,
  571. NRet: cf.NRet,
  572. Parent: cf,
  573. TailCall: 0,
  574. }, lv, meta)
  575. if callGFunction(L, true) {
  576. return 1
  577. }
  578. if L.currentFrame == nil || L.currentFrame.Fn.IsG || luaframe == baseframe {
  579. return 1
  580. }
  581. } else {
  582. base := cf.Base
  583. cf.Fn = callable
  584. cf.Pc = 0
  585. cf.Base = RA
  586. cf.LocalBase = RA + 1
  587. cf.ReturnBase = cf.ReturnBase
  588. cf.NArgs = nargs
  589. cf.NRet = cf.NRet
  590. cf.TailCall++
  591. lbase := cf.LocalBase
  592. if meta {
  593. cf.NArgs++
  594. L.reg.Insert(lv, cf.LocalBase)
  595. }
  596. // +inline-call L.initCallFrame cf
  597. // +inline-call L.reg.CopyRange base RA -1 reg.Top()-RA-1
  598. cf.Base = base
  599. cf.LocalBase = base + (cf.LocalBase - lbase + 1)
  600. }
  601. return 0
  602. },
  603. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_RETURN
  604. reg := L.reg
  605. cf := L.currentFrame
  606. lbase := cf.LocalBase
  607. A := int(inst>>18) & 0xff //GETA
  608. RA := lbase + A
  609. B := int(inst & 0x1ff) //GETB
  610. // +inline-call L.closeUpvalues lbase
  611. nret := B - 1
  612. if B == 0 {
  613. nret = reg.Top() - RA
  614. }
  615. n := cf.NRet
  616. if cf.NRet == MultRet {
  617. n = nret
  618. }
  619. if L.Parent != nil && L.stack.Sp() == 1 {
  620. // +inline-call copyReturnValues L reg.Top() RA n B
  621. switchToParentThread(L, n, false, true)
  622. return 1
  623. }
  624. islast := baseframe == L.stack.Pop() || L.stack.IsEmpty()
  625. // +inline-call copyReturnValues L cf.ReturnBase RA n B
  626. L.currentFrame = L.stack.Last()
  627. if islast || L.currentFrame == nil || L.currentFrame.Fn.IsG {
  628. return 1
  629. }
  630. return 0
  631. },
  632. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORLOOP
  633. reg := L.reg
  634. cf := L.currentFrame
  635. lbase := cf.LocalBase
  636. A := int(inst>>18) & 0xff //GETA
  637. RA := lbase + A
  638. if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
  639. if limit, ok2 := reg.Get(RA + 1).assertFloat64(); ok2 {
  640. if step, ok3 := reg.Get(RA + 2).assertFloat64(); ok3 {
  641. init += step
  642. reg.SetNumber(RA, LNumber(init))
  643. if (step > 0 && init <= limit) || (step <= 0 && init >= limit) {
  644. Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
  645. cf.Pc += Sbx
  646. reg.SetNumber(RA+3, LNumber(init))
  647. } else {
  648. reg.SetTop(RA + 1)
  649. }
  650. } else {
  651. L.RaiseError("for statement step must be a number")
  652. }
  653. } else {
  654. L.RaiseError("for statement limit must be a number")
  655. }
  656. } else {
  657. L.RaiseError("for statement init must be a number")
  658. }
  659. return 0
  660. },
  661. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_FORPREP
  662. reg := L.reg
  663. cf := L.currentFrame
  664. lbase := cf.LocalBase
  665. A := int(inst>>18) & 0xff //GETA
  666. RA := lbase + A
  667. Sbx := int(inst&0x3ffff) - opMaxArgSbx //GETSBX
  668. if init, ok1 := reg.Get(RA).assertFloat64(); ok1 {
  669. if step, ok2 := reg.Get(RA + 2).assertFloat64(); ok2 {
  670. reg.SetNumber(RA, LNumber(init-step))
  671. } else {
  672. L.RaiseError("for statement step must be a number")
  673. }
  674. } else {
  675. L.RaiseError("for statement init must be a number")
  676. }
  677. cf.Pc += Sbx
  678. return 0
  679. },
  680. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_TFORLOOP
  681. reg := L.reg
  682. cf := L.currentFrame
  683. lbase := cf.LocalBase
  684. A := int(inst>>18) & 0xff //GETA
  685. RA := lbase + A
  686. C := int(inst>>9) & 0x1ff //GETC
  687. nret := C
  688. reg.SetTop(RA + 3 + 2)
  689. reg.Set(RA+3+2, reg.Get(RA+2))
  690. reg.Set(RA+3+1, reg.Get(RA+1))
  691. reg.Set(RA+3, reg.Get(RA))
  692. L.callR(2, nret, RA+3)
  693. if value := reg.Get(RA + 3); value != LNil {
  694. reg.Set(RA+2, value)
  695. pc := cf.Fn.Proto.Code[cf.Pc]
  696. cf.Pc += int(pc&0x3ffff) - opMaxArgSbx
  697. }
  698. cf.Pc++
  699. return 0
  700. },
  701. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_SETLIST
  702. reg := L.reg
  703. cf := L.currentFrame
  704. lbase := cf.LocalBase
  705. A := int(inst>>18) & 0xff //GETA
  706. RA := lbase + A
  707. B := int(inst & 0x1ff) //GETB
  708. C := int(inst>>9) & 0x1ff //GETC
  709. if C == 0 {
  710. C = int(cf.Fn.Proto.Code[cf.Pc])
  711. cf.Pc++
  712. }
  713. offset := (C - 1) * FieldsPerFlush
  714. table := reg.Get(RA).(*LTable)
  715. nelem := B
  716. if B == 0 {
  717. nelem = reg.Top() - RA - 1
  718. }
  719. for i := 1; i <= nelem; i++ {
  720. table.RawSetInt(offset+i, reg.Get(RA+i))
  721. }
  722. return 0
  723. },
  724. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSE
  725. cf := L.currentFrame
  726. lbase := cf.LocalBase
  727. A := int(inst>>18) & 0xff //GETA
  728. RA := lbase + A
  729. // +inline-call L.closeUpvalues RA
  730. return 0
  731. },
  732. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_CLOSURE
  733. reg := L.reg
  734. cf := L.currentFrame
  735. lbase := cf.LocalBase
  736. A := int(inst>>18) & 0xff //GETA
  737. RA := lbase + A
  738. Bx := int(inst & 0x3ffff) //GETBX
  739. proto := cf.Fn.Proto.FunctionPrototypes[Bx]
  740. closure := newLFunctionL(proto, cf.Fn.Env, int(proto.NumUpvalues))
  741. reg.Set(RA, closure)
  742. for i := 0; i < int(proto.NumUpvalues); i++ {
  743. inst = cf.Fn.Proto.Code[cf.Pc]
  744. cf.Pc++
  745. B := opGetArgB(inst)
  746. switch opGetOpCode(inst) {
  747. case OP_MOVE:
  748. closure.Upvalues[i] = L.findUpvalue(lbase + B)
  749. case OP_GETUPVAL:
  750. closure.Upvalues[i] = cf.Fn.Upvalues[B]
  751. }
  752. }
  753. return 0
  754. },
  755. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_VARARG
  756. reg := L.reg
  757. cf := L.currentFrame
  758. lbase := cf.LocalBase
  759. A := int(inst>>18) & 0xff //GETA
  760. RA := lbase + A
  761. B := int(inst & 0x1ff) //GETB
  762. nparams := int(cf.Fn.Proto.NumParameters)
  763. nvarargs := cf.NArgs - nparams
  764. if nvarargs < 0 {
  765. nvarargs = 0
  766. }
  767. nwant := B - 1
  768. if B == 0 {
  769. nwant = nvarargs
  770. }
  771. // +inline-call reg.CopyRange RA cf.Base+nparams+1 cf.LocalBase nwant
  772. return 0
  773. },
  774. func(L *LState, inst uint32, baseframe *callFrame) int { //OP_NOP
  775. return 0
  776. },
  777. }
  778. }
  779. func opArith(L *LState, inst uint32, baseframe *callFrame) int { //OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_POW
  780. reg := L.reg
  781. cf := L.currentFrame
  782. lbase := cf.LocalBase
  783. A := int(inst>>18) & 0xff //GETA
  784. RA := lbase + A
  785. opcode := int(inst >> 26) //GETOPCODE
  786. B := int(inst & 0x1ff) //GETB
  787. C := int(inst>>9) & 0x1ff //GETC
  788. lhs := L.rkValue(B)
  789. rhs := L.rkValue(C)
  790. v1, ok1 := lhs.assertFloat64()
  791. v2, ok2 := rhs.assertFloat64()
  792. if ok1 && ok2 {
  793. reg.SetNumber(RA, numberArith(L, opcode, LNumber(v1), LNumber(v2)))
  794. } else {
  795. reg.Set(RA, objectArith(L, opcode, lhs, rhs))
  796. }
  797. return 0
  798. }
  799. func luaModulo(lhs, rhs LNumber) LNumber {
  800. flhs := float64(lhs)
  801. frhs := float64(rhs)
  802. v := math.Mod(flhs, frhs)
  803. if flhs < 0 || frhs < 0 && !(flhs < 0 && frhs < 0) {
  804. v += frhs
  805. }
  806. return LNumber(v)
  807. }
  808. func numberArith(L *LState, opcode int, lhs, rhs LNumber) LNumber {
  809. switch opcode {
  810. case OP_ADD:
  811. return lhs + rhs
  812. case OP_SUB:
  813. return lhs - rhs
  814. case OP_MUL:
  815. return lhs * rhs
  816. case OP_DIV:
  817. return lhs / rhs
  818. case OP_MOD:
  819. return luaModulo(lhs, rhs)
  820. case OP_POW:
  821. flhs := float64(lhs)
  822. frhs := float64(rhs)
  823. return LNumber(math.Pow(flhs, frhs))
  824. }
  825. panic("should not reach here")
  826. return LNumber(0)
  827. }
  828. func objectArith(L *LState, opcode int, lhs, rhs LValue) LValue {
  829. event := ""
  830. switch opcode {
  831. case OP_ADD:
  832. event = "__add"
  833. case OP_SUB:
  834. event = "__sub"
  835. case OP_MUL:
  836. event = "__mul"
  837. case OP_DIV:
  838. event = "__div"
  839. case OP_MOD:
  840. event = "__mod"
  841. case OP_POW:
  842. event = "__pow"
  843. }
  844. op := L.metaOp2(lhs, rhs, event)
  845. if op.Type() == LTFunction {
  846. L.reg.Push(op)
  847. L.reg.Push(lhs)
  848. L.reg.Push(rhs)
  849. L.Call(2, 1)
  850. return L.reg.Pop()
  851. }
  852. if str, ok := lhs.(LString); ok {
  853. if lnum, err := parseNumber(string(str)); err == nil {
  854. lhs = lnum
  855. }
  856. }
  857. if str, ok := rhs.(LString); ok {
  858. if rnum, err := parseNumber(string(str)); err == nil {
  859. rhs = rnum
  860. }
  861. }
  862. if v1, ok1 := lhs.assertFloat64(); ok1 {
  863. if v2, ok2 := rhs.assertFloat64(); ok2 {
  864. return numberArith(L, opcode, LNumber(v1), LNumber(v2))
  865. }
  866. }
  867. L.RaiseError(fmt.Sprintf("cannot perform %v operation between %v and %v",
  868. strings.TrimLeft(event, "_"), lhs.Type().String(), rhs.Type().String()))
  869. return LNil
  870. }
  871. func stringConcat(L *LState, total, last int) LValue {
  872. rhs := L.reg.Get(last)
  873. total--
  874. for i := last - 1; total > 0; {
  875. lhs := L.reg.Get(i)
  876. if !(LVCanConvToString(lhs) && LVCanConvToString(rhs)) {
  877. op := L.metaOp2(lhs, rhs, "__concat")
  878. if op.Type() == LTFunction {
  879. L.reg.Push(op)
  880. L.reg.Push(lhs)
  881. L.reg.Push(rhs)
  882. L.Call(2, 1)
  883. rhs = L.reg.Pop()
  884. total--
  885. i--
  886. } else {
  887. L.RaiseError("cannot perform concat operation between %v and %v", lhs.Type().String(), rhs.Type().String())
  888. return LNil
  889. }
  890. } else {
  891. buf := make([]string, total+1)
  892. buf[total] = LVAsString(rhs)
  893. for total > 0 {
  894. lhs = L.reg.Get(i)
  895. if !LVCanConvToString(lhs) {
  896. break
  897. }
  898. buf[total-1] = LVAsString(lhs)
  899. i--
  900. total--
  901. }
  902. rhs = LString(strings.Join(buf, ""))
  903. }
  904. }
  905. return rhs
  906. }
  907. func lessThan(L *LState, lhs, rhs LValue) bool {
  908. // optimization for numbers
  909. if v1, ok1 := lhs.assertFloat64(); ok1 {
  910. if v2, ok2 := rhs.assertFloat64(); ok2 {
  911. return v1 < v2
  912. }
  913. L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  914. }
  915. if lhs.Type() != rhs.Type() {
  916. L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  917. return false
  918. }
  919. ret := false
  920. switch lhs.Type() {
  921. case LTString:
  922. ret = strCmp(string(lhs.(LString)), string(rhs.(LString))) < 0
  923. default:
  924. ret = objectRationalWithError(L, lhs, rhs, "__lt")
  925. }
  926. return ret
  927. }
  928. func equals(L *LState, lhs, rhs LValue, raw bool) bool {
  929. if lhs.Type() != rhs.Type() {
  930. return false
  931. }
  932. ret := false
  933. switch lhs.Type() {
  934. case LTNil:
  935. ret = true
  936. case LTNumber:
  937. v1, _ := lhs.assertFloat64()
  938. v2, _ := rhs.assertFloat64()
  939. ret = v1 == v2
  940. case LTBool:
  941. ret = bool(lhs.(LBool)) == bool(rhs.(LBool))
  942. case LTString:
  943. ret = string(lhs.(LString)) == string(rhs.(LString))
  944. case LTUserData, LTTable:
  945. if lhs == rhs {
  946. ret = true
  947. } else if !raw {
  948. switch objectRational(L, lhs, rhs, "__eq") {
  949. case 1:
  950. ret = true
  951. default:
  952. ret = false
  953. }
  954. }
  955. default:
  956. ret = lhs == rhs
  957. }
  958. return ret
  959. }
  960. func objectRationalWithError(L *LState, lhs, rhs LValue, event string) bool {
  961. switch objectRational(L, lhs, rhs, event) {
  962. case 1:
  963. return true
  964. case 0:
  965. return false
  966. }
  967. L.RaiseError("attempt to compare %v with %v", lhs.Type().String(), rhs.Type().String())
  968. return false
  969. }
  970. func objectRational(L *LState, lhs, rhs LValue, event string) int {
  971. m1 := L.metaOp1(lhs, event)
  972. m2 := L.metaOp1(rhs, event)
  973. if m1.Type() == LTFunction && m1 == m2 {
  974. L.reg.Push(m1)
  975. L.reg.Push(lhs)
  976. L.reg.Push(rhs)
  977. L.Call(2, 1)
  978. if LVAsBool(L.reg.Pop()) {
  979. return 1
  980. }
  981. return 0
  982. }
  983. return -1
  984. }