_vm.go 26 KB

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