Advertisement
Kep13

LuaK

Dec 21st, 2020
23
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.86 KB | None | 0 0
  1. --[[--------------------------------------------------------------------
  2.  
  3. lcode.lua
  4. Lua 5 code generator in Lua
  5. This file is part of Yueliang.
  6.  
  7. Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
  8. The COPYRIGHT file describes the conditions
  9. under which this software may be distributed.
  10.  
  11. See the ChangeLog for more information.
  12.  
  13. ----------------------------------------------------------------------]]
  14.  
  15. --[[--------------------------------------------------------------------
  16. -- Notes:
  17. -- * one function manipulate a pointer argument with a simple data type
  18. -- (can't be emulated by a table, ambiguous), now returns that value:
  19. -- luaK:concat(fs, l1, l2)
  20. -- * luaM_growvector uses the faux luaY:growvector, for limit checking
  21. -- * some function parameters changed to boolean, additional code
  22. -- translates boolean back to 1/0 for instruction fields
  23. --
  24. -- Not implemented:
  25. -- * NOTE there is a failed assert in luaK:addk, a porting problem
  26. --
  27. -- Added:
  28. -- * constant MAXSTACK from llimits.h
  29. -- * luaK:ttisnumber(o) (from lobject.h)
  30. -- * luaK:nvalue(o) (from lobject.h)
  31. -- * luaK:setnilvalue(o) (from lobject.h)
  32. -- * luaK:setnvalue(o, x) (from lobject.h)
  33. -- * luaK:setbvalue(o, x) (from lobject.h)
  34. -- * luaK:sethvalue(o, x) (from lobject.h), parameter L deleted
  35. -- * luaK:setsvalue(o, x) (from lobject.h), parameter L deleted
  36. -- * luaK:numadd, luaK:numsub, luaK:nummul, luaK:numdiv, luaK:nummod,
  37. -- luaK:numpow, luaK:numunm, luaK:numisnan (from luaconf.h)
  38. -- * copyexp(e1, e2) added in luaK:posfix to copy expdesc struct
  39. --
  40. -- Changed in 5.1.x:
  41. -- * enum BinOpr has a new entry, OPR_MOD
  42. -- * enum UnOpr has a new entry, OPR_LEN
  43. -- * binopistest, unused in 5.0.x, has been deleted
  44. -- * macro setmultret is new
  45. -- * functions isnumeral, luaK_ret, boolK are new
  46. -- * funcion nilK was named nil_constant in 5.0.x
  47. -- * function interface changed: need_value, patchtestreg, concat
  48. -- * TObject now a TValue
  49. -- * functions luaK_setreturns, luaK_setoneret are new
  50. -- * function luaK:setcallreturns deleted, to be replaced by:
  51. -- luaK:setmultret, luaK:ret, luaK:setreturns, luaK:setoneret
  52. -- * functions constfolding, codearith, codecomp are new
  53. -- * luaK:codebinop has been deleted
  54. -- * function luaK_setlist is new
  55. -- * OPR_MULT renamed to OPR_MUL
  56. ----------------------------------------------------------------------]]
  57.  
  58. -- requires luaP, luaX, luaY
  59. local luaK = {}
  60. local luaP = require(script.Parent.LuaP)
  61. local luaX = require(script.Parent.LuaX)
  62.  
  63. ------------------------------------------------------------------------
  64. -- constants used by code generator
  65. ------------------------------------------------------------------------
  66. -- maximum stack for a Lua function
  67. luaK.MAXSTACK = 250 -- (from llimits.h)
  68.  
  69. --[[--------------------------------------------------------------------
  70. -- other functions
  71. ----------------------------------------------------------------------]]
  72.  
  73. ------------------------------------------------------------------------
  74. -- emulation of TValue macros (these are from lobject.h)
  75. -- * TValue is a table since lcode passes references around
  76. -- * tt member field removed, using Lua's type() instead
  77. -- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h
  78. -- is used in an assert for testing, see checkliveness(g,obj)
  79. ------------------------------------------------------------------------
  80. function luaK:ttisnumber(o)
  81. if o then return type(o.value) == "number" else return false end
  82. end
  83. function luaK:nvalue(o) return o.value end
  84. function luaK:setnilvalue(o) o.value = nil end
  85. function luaK:setsvalue(o, x) o.value = x end
  86. luaK.setnvalue = luaK.setsvalue
  87. luaK.sethvalue = luaK.setsvalue
  88. luaK.setbvalue = luaK.setsvalue
  89.  
  90. ------------------------------------------------------------------------
  91. -- The luai_num* macros define the primitive operations over numbers.
  92. -- * this is not the entire set of primitive operations from luaconf.h
  93. -- * used in luaK:constfolding()
  94. ------------------------------------------------------------------------
  95. function luaK:numadd(a, b) return a + b end
  96. function luaK:numsub(a, b) return a - b end
  97. function luaK:nummul(a, b) return a * b end
  98. function luaK:numdiv(a, b) return a / b end
  99. function luaK:nummod(a, b) return a % b end
  100. -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */
  101. function luaK:numpow(a, b) return a ^ b end
  102. function luaK:numunm(a) return -a end
  103. function luaK:numisnan(a) return not a == a end
  104. -- a NaN cannot equal another NaN
  105.  
  106. --[[--------------------------------------------------------------------
  107. -- code generator functions
  108. ----------------------------------------------------------------------]]
  109.  
  110. ------------------------------------------------------------------------
  111. -- Marks the end of a patch list. It is an invalid value both as an absolute
  112. -- address, and as a list link (would link an element to itself).
  113. ------------------------------------------------------------------------
  114. luaK.NO_JUMP = -1
  115.  
  116. ------------------------------------------------------------------------
  117. -- grep "ORDER OPR" if you change these enums
  118. ------------------------------------------------------------------------
  119. luaK.BinOpr = {
  120. OPR_ADD = 0, OPR_SUB = 1, OPR_MUL = 2, OPR_DIV = 3, OPR_MOD = 4, OPR_POW = 5,
  121. OPR_CONCAT = 6,
  122. OPR_NE = 7, OPR_EQ = 8,
  123. OPR_LT = 9, OPR_LE = 10, OPR_GT = 11, OPR_GE = 12,
  124. OPR_AND = 13, OPR_OR = 14,
  125. OPR_NOBINOPR = 15,
  126. }
  127.  
  128. -- * UnOpr is used by luaK:prefix's op argument, but not directly used
  129. -- because the function receives the symbols as strings, e.g. "OPR_NOT"
  130. luaK.UnOpr = {
  131. OPR_MINUS = 0, OPR_NOT = 1, OPR_LEN = 2, OPR_NOUNOPR = 3
  132. }
  133.  
  134. ------------------------------------------------------------------------
  135. -- returns the instruction object for given e (expdesc), was a macro
  136. ------------------------------------------------------------------------
  137. function luaK:getcode(fs, e)
  138. return fs.f.code[e.info]
  139. end
  140.  
  141. ------------------------------------------------------------------------
  142. -- codes an instruction with a signed Bx (sBx) field, was a macro
  143. -- * used in luaK:jump(), (lparser) luaY:forbody()
  144. ------------------------------------------------------------------------
  145. function luaK:codeAsBx(fs, o, A, sBx)
  146. return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx)
  147. end
  148.  
  149. ------------------------------------------------------------------------
  150. -- set the expdesc e instruction for multiple returns, was a macro
  151. ------------------------------------------------------------------------
  152. function luaK:setmultret(fs, e)
  153. self:setreturns(fs, e, luaY.LUA_MULTRET)
  154. end
  155.  
  156. ------------------------------------------------------------------------
  157. -- there is a jump if patch lists are not identical, was a macro
  158. -- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val()
  159. ------------------------------------------------------------------------
  160. function luaK:hasjumps(e)
  161. return e.t ~= e.f
  162. end
  163.  
  164. ------------------------------------------------------------------------
  165. -- true if the expression is a constant number (for constant folding)
  166. -- * used in constfolding(), infix()
  167. ------------------------------------------------------------------------
  168. function luaK:isnumeral(e)
  169. return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP
  170. end
  171.  
  172. ------------------------------------------------------------------------
  173. -- codes loading of nil, optimization done if consecutive locations
  174. -- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign()
  175. ------------------------------------------------------------------------
  176. function luaK:_nil(fs, from, n)
  177. if fs.pc > fs.lasttarget then -- no jumps to current position?
  178. if fs.pc == 0 then -- function start?
  179. if from >= fs.nactvar then
  180. return -- positions are already clean
  181. end
  182. else
  183. local previous = fs.f.code[fs.pc - 1]
  184. if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then
  185. local pfrom = luaP:GETARG_A(previous)
  186. local pto = luaP:GETARG_B(previous)
  187. if pfrom <= from and from <= pto + 1 then -- can connect both?
  188. if from + n - 1 > pto then
  189. luaP:SETARG_B(previous, from + n - 1)
  190. end
  191. return
  192. end
  193. end
  194. end
  195. end
  196. self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization
  197. end
  198.  
  199. ------------------------------------------------------------------------
  200. --
  201. -- * used in multiple locations
  202. ------------------------------------------------------------------------
  203. function luaK:jump(fs)
  204. local jpc = fs.jpc -- save list of jumps to here
  205. fs.jpc = self.NO_JUMP
  206. local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP)
  207. j = self:concat(fs, j, jpc) -- keep them on hold
  208. return j
  209. end
  210.  
  211. ------------------------------------------------------------------------
  212. -- codes a RETURN instruction
  213. -- * used in luaY:close_func(), luaY:retstat()
  214. ------------------------------------------------------------------------
  215. function luaK:ret(fs, first, nret)
  216. self:codeABC(fs, "OP_RETURN", first, nret + 1, 0)
  217. end
  218.  
  219. ------------------------------------------------------------------------
  220. --
  221. -- * used in luaK:jumponcond(), luaK:codecomp()
  222. ------------------------------------------------------------------------
  223. function luaK:condjump(fs, op, A, B, C)
  224. self:codeABC(fs, op, A, B, C)
  225. return self:jump(fs)
  226. end
  227.  
  228. ------------------------------------------------------------------------
  229. --
  230. -- * used in luaK:patchlistaux(), luaK:concat()
  231. ------------------------------------------------------------------------
  232. function luaK:fixjump(fs, pc, dest)
  233. local jmp = fs.f.code[pc]
  234. local offset = dest - (pc + 1)
  235. assert(dest ~= self.NO_JUMP)
  236. if math.abs(offset) > luaP.MAXARG_sBx then
  237. luaX:syntaxerror(fs.ls, "control structure too long")
  238. end
  239. luaP:SETARG_sBx(jmp, offset)
  240. end
  241.  
  242. ------------------------------------------------------------------------
  243. -- returns current 'pc' and marks it as a jump target (to avoid wrong
  244. -- optimizations with consecutive instructions not in the same basic block).
  245. -- * used in multiple locations
  246. -- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL
  247. ------------------------------------------------------------------------
  248. function luaK:getlabel(fs)
  249. fs.lasttarget = fs.pc
  250. return fs.pc
  251. end
  252.  
  253. ------------------------------------------------------------------------
  254. --
  255. -- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(),
  256. -- luaK:concat()
  257. ------------------------------------------------------------------------
  258. function luaK:getjump(fs, pc)
  259. local offset = luaP:GETARG_sBx(fs.f.code[pc])
  260. if offset == self.NO_JUMP then -- point to itself represents end of list
  261. return self.NO_JUMP -- end of list
  262. else
  263. return (pc + 1) + offset -- turn offset into absolute position
  264. end
  265. end
  266.  
  267. ------------------------------------------------------------------------
  268. --
  269. -- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump()
  270. ------------------------------------------------------------------------
  271. function luaK:getjumpcontrol(fs, pc)
  272. local pi = fs.f.code[pc]
  273. local ppi = fs.f.code[pc - 1]
  274. if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 then
  275. return ppi
  276. else
  277. return pi
  278. end
  279. end
  280.  
  281. ------------------------------------------------------------------------
  282. -- check whether list has any jump that do not produce a value
  283. -- (or produce an inverted value)
  284. -- * return value changed to boolean
  285. -- * used only in luaK:exp2reg()
  286. ------------------------------------------------------------------------
  287. function luaK:need_value(fs, list)
  288. while list ~= self.NO_JUMP do
  289. local i = self:getjumpcontrol(fs, list)
  290. if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then return true end
  291. list = self:getjump(fs, list)
  292. end
  293. return false -- not found
  294. end
  295.  
  296. ------------------------------------------------------------------------
  297. --
  298. -- * used in luaK:removevalues(), luaK:patchlistaux()
  299. ------------------------------------------------------------------------
  300. function luaK:patchtestreg(fs, node, reg)
  301. local i = self:getjumpcontrol(fs, node)
  302. if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then
  303. return false -- cannot patch other instructions
  304. end
  305. if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then
  306. luaP:SETARG_A(i, reg)
  307. else -- no register to put value or register already has the value
  308. -- due to use of a table as i, i cannot be replaced by another table
  309. -- so the following is required; there is no change to ARG_C
  310. luaP:SET_OPCODE(i, "OP_TEST")
  311. local b = luaP:GETARG_B(i)
  312. luaP:SETARG_A(i, b)
  313. luaP:SETARG_B(i, 0)
  314. -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */
  315. end
  316. return true
  317. end
  318.  
  319. ------------------------------------------------------------------------
  320. --
  321. -- * used only in luaK:codenot()
  322. ------------------------------------------------------------------------
  323. function luaK:removevalues(fs, list)
  324. while list ~= self.NO_JUMP do
  325. self:patchtestreg(fs, list, luaP.NO_REG)
  326. list = self:getjump(fs, list)
  327. end
  328. end
  329.  
  330. ------------------------------------------------------------------------
  331. --
  332. -- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg()
  333. ------------------------------------------------------------------------
  334. function luaK:patchlistaux(fs, list, vtarget, reg, dtarget)
  335. while list ~= self.NO_JUMP do
  336. local _next = self:getjump(fs, list)
  337. if self:patchtestreg(fs, list, reg) then
  338. self:fixjump(fs, list, vtarget)
  339. else
  340. self:fixjump(fs, list, dtarget) -- jump to default target
  341. end
  342. list = _next
  343. end
  344. end
  345.  
  346. ------------------------------------------------------------------------
  347. --
  348. -- * used only in luaK:code()
  349. ------------------------------------------------------------------------
  350. function luaK:dischargejpc(fs)
  351. self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc)
  352. fs.jpc = self.NO_JUMP
  353. end
  354.  
  355. ------------------------------------------------------------------------
  356. --
  357. -- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody()
  358. ------------------------------------------------------------------------
  359. function luaK:patchlist(fs, list, target)
  360. if target == fs.pc then
  361. self:patchtohere(fs, list)
  362. else
  363. assert(target < fs.pc)
  364. self:patchlistaux(fs, list, target, luaP.NO_REG, target)
  365. end
  366. end
  367.  
  368. ------------------------------------------------------------------------
  369. --
  370. -- * used in multiple locations
  371. ------------------------------------------------------------------------
  372. function luaK:patchtohere(fs, list)
  373. self:getlabel(fs)
  374. fs.jpc = self:concat(fs, fs.jpc, list)
  375. end
  376.  
  377. ------------------------------------------------------------------------
  378. -- * l1 was a pointer, now l1 is returned and callee assigns the value
  379. -- * used in multiple locations
  380. ------------------------------------------------------------------------
  381. function luaK:concat(fs, l1, l2)
  382. if l2 == self.NO_JUMP then return l1
  383. elseif l1 == self.NO_JUMP then
  384. return l2
  385. else
  386. local list = l1
  387. local _next = self:getjump(fs, list)
  388. while _next ~= self.NO_JUMP do -- find last element
  389. list = _next
  390. _next = self:getjump(fs, list)
  391. end
  392. self:fixjump(fs, list, l2)
  393. end
  394. return l1
  395. end
  396.  
  397. ------------------------------------------------------------------------
  398. --
  399. -- * used in luaK:reserveregs(), (lparser) luaY:forlist()
  400. ------------------------------------------------------------------------
  401. function luaK:checkstack(fs, n)
  402. local newstack = fs.freereg + n
  403. if newstack > fs.f.maxstacksize then
  404. if newstack >= self.MAXSTACK then
  405. luaX:syntaxerror(fs.ls, "function or expression too complex")
  406. end
  407. fs.f.maxstacksize = newstack
  408. end
  409. end
  410.  
  411. ------------------------------------------------------------------------
  412. --
  413. -- * used in multiple locations
  414. ------------------------------------------------------------------------
  415. function luaK:reserveregs(fs, n)
  416. self:checkstack(fs, n)
  417. fs.freereg = fs.freereg + n
  418. end
  419.  
  420. ------------------------------------------------------------------------
  421. --
  422. -- * used in luaK:freeexp(), luaK:dischargevars()
  423. ------------------------------------------------------------------------
  424. function luaK:freereg(fs, reg)
  425. if not luaP:ISK(reg) and reg >= fs.nactvar then
  426. fs.freereg = fs.freereg - 1
  427. assert(reg == fs.freereg)
  428. end
  429. end
  430.  
  431. ------------------------------------------------------------------------
  432. --
  433. -- * used in multiple locations
  434. ------------------------------------------------------------------------
  435. function luaK:freeexp(fs, e)
  436. if e.k == "VNONRELOC" then
  437. self:freereg(fs, e.info)
  438. end
  439. end
  440.  
  441. ------------------------------------------------------------------------
  442. -- * TODO NOTE implementation is not 100% correct, since the assert fails
  443. -- * luaH_set, setobj deleted; direct table access used instead
  444. -- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK()
  445. ------------------------------------------------------------------------
  446. function luaK:addk(fs, k, v)
  447. local L = fs.L
  448. local idx = fs.h[k.value]
  449. --TValue *idx = luaH_set(L, fs->h, k); /* C */
  450. local f = fs.f
  451. if self:ttisnumber(idx) then
  452. --TODO this assert currently FAILS (last tested for 5.0.2)
  453. --assert(fs.f.k[self:nvalue(idx)] == v)
  454. --assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */
  455. return self:nvalue(idx)
  456. else -- constant not found; create a new entry
  457. idx = {}
  458. self:setnvalue(idx, fs.nk)
  459. fs.h[k.value] = idx
  460. -- setnvalue(idx, cast_num(fs->nk)); /* C */
  461. luaY:growvector(L, f.k, fs.nk, f.sizek, nil,
  462. luaP.MAXARG_Bx, "constant table overflow")
  463. -- loop to initialize empty f.k positions not required
  464. f.k[fs.nk] = v
  465. -- setobj(L, &f->k[fs->nk], v); /* C */
  466. -- luaC_barrier(L, f, v); /* GC */
  467. local nk = fs.nk
  468. fs.nk = fs.nk + 1
  469. return nk
  470. end
  471.  
  472. end
  473.  
  474. ------------------------------------------------------------------------
  475. -- creates and sets a string object
  476. -- * used in (lparser) luaY:codestring(), luaY:singlevar()
  477. ------------------------------------------------------------------------
  478. function luaK:stringK(fs, s)
  479. local o = {} -- TValue
  480. self:setsvalue(o, s)
  481. return self:addk(fs, o, o)
  482. end
  483.  
  484. ------------------------------------------------------------------------
  485. -- creates and sets a number object
  486. -- * used in luaK:prefix() for negative (or negation of) numbers
  487. -- * used in (lparser) luaY:simpleexp(), luaY:fornum()
  488. ------------------------------------------------------------------------
  489. function luaK:numberK(fs, r)
  490. local o = {} -- TValue
  491. self:setnvalue(o, r)
  492. return self:addk(fs, o, o)
  493. end
  494.  
  495. ------------------------------------------------------------------------
  496. -- creates and sets a boolean object
  497. -- * used only in luaK:exp2RK()
  498. ------------------------------------------------------------------------
  499. function luaK:boolK(fs, b)
  500. local o = {} -- TValue
  501. self:setbvalue(o, b)
  502. return self:addk(fs, o, o)
  503. end
  504.  
  505. ------------------------------------------------------------------------
  506. -- creates and sets a nil object
  507. -- * used only in luaK:exp2RK()
  508. ------------------------------------------------------------------------
  509. function luaK:nilK(fs)
  510. local k, v = {}, {} -- TValue
  511. self:setnilvalue(v)
  512. -- cannot use nil as key; instead use table itself to represent nil
  513. self:sethvalue(k, fs.h)
  514. return self:addk(fs, k, v)
  515. end
  516.  
  517. ------------------------------------------------------------------------
  518. --
  519. -- * used in luaK:setmultret(), (lparser) luaY:adjust_assign()
  520. ------------------------------------------------------------------------
  521. function luaK:setreturns(fs, e, nresults)
  522. if e.k == "VCALL" then -- expression is an open function call?
  523. luaP:SETARG_C(self:getcode(fs, e), nresults + 1)
  524. elseif e.k == "VVARARG" then
  525. luaP:SETARG_B(self:getcode(fs, e), nresults + 1);
  526. luaP:SETARG_A(self:getcode(fs, e), fs.freereg);
  527. luaK:reserveregs(fs, 1)
  528. end
  529. end
  530.  
  531. ------------------------------------------------------------------------
  532. --
  533. -- * used in luaK:dischargevars(), (lparser) luaY:assignment()
  534. ------------------------------------------------------------------------
  535. function luaK:setoneret(fs, e)
  536. if e.k == "VCALL" then -- expression is an open function call?
  537. e.k = "VNONRELOC"
  538. e.info = luaP:GETARG_A(self:getcode(fs, e))
  539. elseif e.k == "VVARARG" then
  540. luaP:SETARG_B(self:getcode(fs, e), 2)
  541. e.k = "VRELOCABLE" -- can relocate its simple result
  542. end
  543. end
  544.  
  545. ------------------------------------------------------------------------
  546. --
  547. -- * used in multiple locations
  548. ------------------------------------------------------------------------
  549. function luaK:dischargevars(fs, e)
  550. local k = e.k
  551. if k == "VLOCAL" then
  552. e.k = "VNONRELOC"
  553. elseif k == "VUPVAL" then
  554. e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0)
  555. e.k = "VRELOCABLE"
  556. elseif k == "VGLOBAL" then
  557. e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info)
  558. e.k = "VRELOCABLE"
  559. elseif k == "VINDEXED" then
  560. self:freereg(fs, e.aux)
  561. self:freereg(fs, e.info)
  562. e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux)
  563. e.k = "VRELOCABLE"
  564. elseif k == "VVARARG" or k == "VCALL" then
  565. self:setoneret(fs, e)
  566. else
  567. -- there is one value available (somewhere)
  568. end
  569. end
  570.  
  571. ------------------------------------------------------------------------
  572. --
  573. -- * used only in luaK:exp2reg()
  574. ------------------------------------------------------------------------
  575. function luaK:code_label(fs, A, b, jump)
  576. self:getlabel(fs) -- those instructions may be jump targets
  577. return self:codeABC(fs, "OP_LOADBOOL", A, b, jump)
  578. end
  579.  
  580. ------------------------------------------------------------------------
  581. --
  582. -- * used in luaK:discharge2anyreg(), luaK:exp2reg()
  583. ------------------------------------------------------------------------
  584. function luaK:discharge2reg(fs, e, reg)
  585. self:dischargevars(fs, e)
  586. local k = e.k
  587. if k == "VNIL" then
  588. self:_nil(fs, reg, 1)
  589. elseif k == "VFALSE" or k == "VTRUE" then
  590. self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0)
  591. elseif k == "VK" then
  592. self:codeABx(fs, "OP_LOADK", reg, e.info)
  593. elseif k == "VKNUM" then
  594. self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval))
  595. elseif k == "VRELOCABLE" then
  596. local pc = self:getcode(fs, e)
  597. luaP:SETARG_A(pc, reg)
  598. elseif k == "VNONRELOC" then
  599. if reg ~= e.info then
  600. self:codeABC(fs, "OP_MOVE", reg, e.info, 0)
  601. end
  602. else
  603. assert(e.k == "VVOID" or e.k == "VJMP")
  604. return -- nothing to do...
  605. end
  606. e.info = reg
  607. e.k = "VNONRELOC"
  608. end
  609.  
  610. ------------------------------------------------------------------------
  611. --
  612. -- * used in luaK:jumponcond(), luaK:codenot()
  613. ------------------------------------------------------------------------
  614. function luaK:discharge2anyreg(fs, e)
  615. if e.k ~= "VNONRELOC" then
  616. self:reserveregs(fs, 1)
  617. self:discharge2reg(fs, e, fs.freereg - 1)
  618. end
  619. end
  620.  
  621. ------------------------------------------------------------------------
  622. --
  623. -- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar()
  624. ------------------------------------------------------------------------
  625. function luaK:exp2reg(fs, e, reg)
  626. self:discharge2reg(fs, e, reg)
  627. if e.k == "VJMP" then
  628. e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list
  629. end
  630. if self:hasjumps(e) then
  631. local final -- position after whole expression
  632. local p_f = self.NO_JUMP -- position of an eventual LOAD false
  633. local p_t = self.NO_JUMP -- position of an eventual LOAD true
  634. if self:need_value(fs, e.t) or self:need_value(fs, e.f) then
  635. local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs)
  636. p_f = self:code_label(fs, reg, 0, 1)
  637. p_t = self:code_label(fs, reg, 1, 0)
  638. self:patchtohere(fs, fj)
  639. end
  640. final = self:getlabel(fs)
  641. self:patchlistaux(fs, e.f, final, reg, p_f)
  642. self:patchlistaux(fs, e.t, final, reg, p_t)
  643. end
  644. e.f, e.t = self.NO_JUMP, self.NO_JUMP
  645. e.info = reg
  646. e.k = "VNONRELOC"
  647. end
  648.  
  649. ------------------------------------------------------------------------
  650. --
  651. -- * used in multiple locations
  652. ------------------------------------------------------------------------
  653. function luaK:exp2nextreg(fs, e)
  654. self:dischargevars(fs, e)
  655. self:freeexp(fs, e)
  656. self:reserveregs(fs, 1)
  657. self:exp2reg(fs, e, fs.freereg - 1)
  658. end
  659.  
  660. ------------------------------------------------------------------------
  661. --
  662. -- * used in multiple locations
  663. ------------------------------------------------------------------------
  664. function luaK:exp2anyreg(fs, e)
  665. self:dischargevars(fs, e)
  666. if e.k == "VNONRELOC" then
  667. if not self:hasjumps(e) then -- exp is already in a register
  668. return e.info
  669. end
  670. if e.info >= fs.nactvar then -- reg. is not a local?
  671. self:exp2reg(fs, e, e.info) -- put value on it
  672. return e.info
  673. end
  674. end
  675. self:exp2nextreg(fs, e) -- default
  676. return e.info
  677. end
  678.  
  679. ------------------------------------------------------------------------
  680. --
  681. -- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix()
  682. -- * used in (lparser) luaY:yindex()
  683. ------------------------------------------------------------------------
  684. function luaK:exp2val(fs, e)
  685. if self:hasjumps(e) then
  686. self:exp2anyreg(fs, e)
  687. else
  688. self:dischargevars(fs, e)
  689. end
  690. end
  691.  
  692. ------------------------------------------------------------------------
  693. --
  694. -- * used in multiple locations
  695. ------------------------------------------------------------------------
  696. function luaK:exp2RK(fs, e)
  697. self:exp2val(fs, e)
  698. local k = e.k
  699. if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then
  700. if fs.nk <= luaP.MAXINDEXRK then -- constant fit in RK operand?
  701. -- converted from a 2-deep ternary operator expression
  702. if e.k == "VNIL" then
  703. e.info = self:nilK(fs)
  704. else
  705. e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval)
  706. or self:boolK(fs, e.k == "VTRUE")
  707. end
  708. e.k = "VK"
  709. return luaP:RKASK(e.info)
  710. end
  711. elseif k == "VK" then
  712. if e.info <= luaP.MAXINDEXRK then -- constant fit in argC?
  713. return luaP:RKASK(e.info)
  714. end
  715. else
  716. -- default
  717. end
  718. -- not a constant in the right range: put it in a register
  719. return self:exp2anyreg(fs, e)
  720. end
  721.  
  722. ------------------------------------------------------------------------
  723. --
  724. -- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat()
  725. ------------------------------------------------------------------------
  726. function luaK:storevar(fs, var, ex)
  727. local k = var.k
  728. if k == "VLOCAL" then
  729. self:freeexp(fs, ex)
  730. self:exp2reg(fs, ex, var.info)
  731. return
  732. elseif k == "VUPVAL" then
  733. local e = self:exp2anyreg(fs, ex)
  734. self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0)
  735. elseif k == "VGLOBAL" then
  736. local e = self:exp2anyreg(fs, ex)
  737. self:codeABx(fs, "OP_SETGLOBAL", e, var.info)
  738. elseif k == "VINDEXED" then
  739. local e = self:exp2RK(fs, ex)
  740. self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e)
  741. else
  742. assert(0) -- invalid var kind to store
  743. end
  744. self:freeexp(fs, ex)
  745. end
  746.  
  747. ------------------------------------------------------------------------
  748. --
  749. -- * used only in (lparser) luaY:primaryexp()
  750. ------------------------------------------------------------------------
  751. function luaK:_self(fs, e, key)
  752. self:exp2anyreg(fs, e)
  753. self:freeexp(fs, e)
  754. local func = fs.freereg
  755. self:reserveregs(fs, 2)
  756. self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key))
  757. self:freeexp(fs, key)
  758. e.info = func
  759. e.k = "VNONRELOC"
  760. end
  761.  
  762. ------------------------------------------------------------------------
  763. --
  764. -- * used in luaK:goiftrue(), luaK:codenot()
  765. ------------------------------------------------------------------------
  766. function luaK:invertjump(fs, e)
  767. local pc = self:getjumpcontrol(fs, e.info)
  768. assert(luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0 and
  769. luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and
  770. luaP:GET_OPCODE(pc) ~= "OP_TEST")
  771. luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0)
  772. end
  773.  
  774. ------------------------------------------------------------------------
  775. --
  776. -- * used in luaK:goiftrue(), luaK:goiffalse()
  777. ------------------------------------------------------------------------
  778. function luaK:jumponcond(fs, e, cond)
  779. if e.k == "VRELOCABLE" then
  780. local ie = self:getcode(fs, e)
  781. if luaP:GET_OPCODE(ie) == "OP_NOT" then
  782. fs.pc = fs.pc - 1 -- remove previous OP_NOT
  783. return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, cond and 0 or 1)
  784. end
  785. -- else go through
  786. end
  787. self:discharge2anyreg(fs, e)
  788. self:freeexp(fs, e)
  789. return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0)
  790. end
  791.  
  792. ------------------------------------------------------------------------
  793. --
  794. -- * used in luaK:infix(), (lparser) luaY:cond()
  795. ------------------------------------------------------------------------
  796. function luaK:goiftrue(fs, e)
  797. local pc -- pc of last jump
  798. self:dischargevars(fs, e)
  799. local k = e.k
  800. if k == "VK" or k == "VKNUM" or k == "VTRUE" then
  801. pc = self.NO_JUMP -- always true; do nothing
  802. elseif k == "VFALSE" then
  803. pc = self:jump(fs) -- always jump
  804. elseif k == "VJMP" then
  805. self:invertjump(fs, e)
  806. pc = e.info
  807. else
  808. pc = self:jumponcond(fs, e, false)
  809. end
  810. e.f = self:concat(fs, e.f, pc) -- insert last jump in `f' list
  811. self:patchtohere(fs, e.t)
  812. e.t = self.NO_JUMP
  813. end
  814.  
  815. ------------------------------------------------------------------------
  816. --
  817. -- * used in luaK:infix()
  818. ------------------------------------------------------------------------
  819. function luaK:goiffalse(fs, e)
  820. local pc -- pc of last jump
  821. self:dischargevars(fs, e)
  822. local k = e.k
  823. if k == "VNIL" or k == "VFALSE"then
  824. pc = self.NO_JUMP -- always false; do nothing
  825. elseif k == "VTRUE" then
  826. pc = self:jump(fs) -- always jump
  827. elseif k == "VJMP" then
  828. pc = e.info
  829. else
  830. pc = self:jumponcond(fs, e, true)
  831. end
  832. e.t = self:concat(fs, e.t, pc) -- insert last jump in `t' list
  833. self:patchtohere(fs, e.f)
  834. e.f = self.NO_JUMP
  835. end
  836.  
  837. ------------------------------------------------------------------------
  838. --
  839. -- * used only in luaK:prefix()
  840. ------------------------------------------------------------------------
  841. function luaK:codenot(fs, e)
  842. self:dischargevars(fs, e)
  843. local k = e.k
  844. if k == "VNIL" or k == "VFALSE" then
  845. e.k = "VTRUE"
  846. elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then
  847. e.k = "VFALSE"
  848. elseif k == "VJMP" then
  849. self:invertjump(fs, e)
  850. elseif k == "VRELOCABLE" or k == "VNONRELOC" then
  851. self:discharge2anyreg(fs, e)
  852. self:freeexp(fs, e)
  853. e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0)
  854. e.k = "VRELOCABLE"
  855. else
  856. assert(0) -- cannot happen
  857. end
  858. -- interchange true and false lists
  859. e.f, e.t = e.t, e.f
  860. self:removevalues(fs, e.f)
  861. self:removevalues(fs, e.t)
  862. end
  863.  
  864. ------------------------------------------------------------------------
  865. --
  866. -- * used in (lparser) luaY:field(), luaY:primaryexp()
  867. ------------------------------------------------------------------------
  868. function luaK:indexed(fs, t, k)
  869. t.aux = self:exp2RK(fs, k)
  870. t.k = "VINDEXED"
  871. end
  872.  
  873. ------------------------------------------------------------------------
  874. --
  875. -- * used only in luaK:codearith()
  876. ------------------------------------------------------------------------
  877. function luaK:constfolding(op, e1, e2)
  878. local r
  879. if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end
  880. local v1 = e1.nval
  881. local v2 = e2.nval
  882. if op == "OP_ADD" then
  883. r = self:numadd(v1, v2)
  884. elseif op == "OP_SUB" then
  885. r = self:numsub(v1, v2)
  886. elseif op == "OP_MUL" then
  887. r = self:nummul(v1, v2)
  888. elseif op == "OP_DIV" then
  889. if v2 == 0 then return false end -- do not attempt to divide by 0
  890. r = self:numdiv(v1, v2)
  891. elseif op == "OP_MOD" then
  892. if v2 == 0 then return false end -- do not attempt to divide by 0
  893. r = self:nummod(v1, v2)
  894. elseif op == "OP_POW" then
  895. r = self:numpow(v1, v2)
  896. elseif op == "OP_UNM" then
  897. r = self:numunm(v1)
  898. elseif op == "OP_LEN" then
  899. return false -- no constant folding for 'len'
  900. else
  901. assert(0)
  902. r = 0
  903. end
  904. if self:numisnan(r) then return false end -- do not attempt to produce NaN
  905. e1.nval = r
  906. return true
  907. end
  908.  
  909. ------------------------------------------------------------------------
  910. --
  911. -- * used in luaK:prefix(), luaK:posfix()
  912. ------------------------------------------------------------------------
  913. function luaK:codearith(fs, op, e1, e2)
  914. if self:constfolding(op, e1, e2) then
  915. return
  916. else
  917. local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0
  918. local o1 = self:exp2RK(fs, e1)
  919. if o1 > o2 then
  920. self:freeexp(fs, e1)
  921. self:freeexp(fs, e2)
  922. else
  923. self:freeexp(fs, e2)
  924. self:freeexp(fs, e1)
  925. end
  926. e1.info = self:codeABC(fs, op, 0, o1, o2)
  927. e1.k = "VRELOCABLE"
  928. end
  929. end
  930.  
  931. ------------------------------------------------------------------------
  932. --
  933. -- * used only in luaK:posfix()
  934. ------------------------------------------------------------------------
  935. function luaK:codecomp(fs, op, cond, e1, e2)
  936. local o1 = self:exp2RK(fs, e1)
  937. local o2 = self:exp2RK(fs, e2)
  938. self:freeexp(fs, e2)
  939. self:freeexp(fs, e1)
  940. if cond == 0 and op ~= "OP_EQ" then
  941. -- exchange args to replace by `<' or `<='
  942. o1, o2 = o2, o1 -- o1 <==> o2
  943. cond = 1
  944. end
  945. e1.info = self:condjump(fs, op, cond, o1, o2)
  946. e1.k = "VJMP"
  947. end
  948.  
  949. ------------------------------------------------------------------------
  950. --
  951. -- * used only in (lparser) luaY:subexpr()
  952. ------------------------------------------------------------------------
  953. function luaK:prefix(fs, op, e)
  954. local e2 = {} -- expdesc
  955. e2.t, e2.f = self.NO_JUMP, self.NO_JUMP
  956. e2.k = "VKNUM"
  957. e2.nval = 0
  958. if op == "OPR_MINUS" then
  959. if not self:isnumeral(e) then
  960. self:exp2anyreg(fs, e) -- cannot operate on non-numeric constants
  961. end
  962. self:codearith(fs, "OP_UNM", e, e2)
  963. elseif op == "OPR_NOT" then
  964. self:codenot(fs, e)
  965. elseif op == "OPR_LEN" then
  966. self:exp2anyreg(fs, e) -- cannot operate on constants
  967. self:codearith(fs, "OP_LEN", e, e2)
  968. else
  969. assert(0)
  970. end
  971. end
  972.  
  973. ------------------------------------------------------------------------
  974. --
  975. -- * used only in (lparser) luaY:subexpr()
  976. ------------------------------------------------------------------------
  977. function luaK:infix(fs, op, v)
  978. if op == "OPR_AND" then
  979. self:goiftrue(fs, v)
  980. elseif op == "OPR_OR" then
  981. self:goiffalse(fs, v)
  982. elseif op == "OPR_CONCAT" then
  983. self:exp2nextreg(fs, v) -- operand must be on the 'stack'
  984. elseif op == "OPR_ADD" or op == "OPR_SUB" or
  985. op == "OPR_MUL" or op == "OPR_DIV" or
  986. op == "OPR_MOD" or op == "OPR_POW" then
  987. if not self:isnumeral(v) then self:exp2RK(fs, v) end
  988. else
  989. self:exp2RK(fs, v)
  990. end
  991. end
  992.  
  993. ------------------------------------------------------------------------
  994. --
  995. -- * used only in (lparser) luaY:subexpr()
  996. ------------------------------------------------------------------------
  997. -- table lookups to simplify testing
  998. luaK.arith_op = {
  999. OPR_ADD = "OP_ADD", OPR_SUB = "OP_SUB", OPR_MUL = "OP_MUL",
  1000. OPR_DIV = "OP_DIV", OPR_MOD = "OP_MOD", OPR_POW = "OP_POW",
  1001. }
  1002. luaK.comp_op = {
  1003. OPR_EQ = "OP_EQ", OPR_NE = "OP_EQ", OPR_LT = "OP_LT",
  1004. OPR_LE = "OP_LE", OPR_GT = "OP_LT", OPR_GE = "OP_LE",
  1005. }
  1006. luaK.comp_cond = {
  1007. OPR_EQ = 1, OPR_NE = 0, OPR_LT = 1,
  1008. OPR_LE = 1, OPR_GT = 0, OPR_GE = 0,
  1009. }
  1010. function luaK:posfix(fs, op, e1, e2)
  1011. -- needed because e1 = e2 doesn't copy values...
  1012. -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR
  1013. -- but here, all elements are copied for completeness' sake
  1014. local function copyexp(e1, e2)
  1015. e1.k = e2.k
  1016. e1.info = e2.info; e1.aux = e2.aux
  1017. e1.nval = e2.nval
  1018. e1.t = e2.t; e1.f = e2.f
  1019. end
  1020. if op == "OPR_AND" then
  1021. assert(e1.t == self.NO_JUMP) -- list must be closed
  1022. self:dischargevars(fs, e2)
  1023. e2.f = self:concat(fs, e2.f, e1.f)
  1024. copyexp(e1, e2)
  1025. elseif op == "OPR_OR" then
  1026. assert(e1.f == self.NO_JUMP) -- list must be closed
  1027. self:dischargevars(fs, e2)
  1028. e2.t = self:concat(fs, e2.t, e1.t)
  1029. copyexp(e1, e2)
  1030. elseif op == "OPR_CONCAT" then
  1031. self:exp2val(fs, e2)
  1032. if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then
  1033. assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1)
  1034. self:freeexp(fs, e1)
  1035. luaP:SETARG_B(self:getcode(fs, e2), e1.info)
  1036. e1.k = "VRELOCABLE"
  1037. e1.info = e2.info
  1038. else
  1039. self:exp2nextreg(fs, e2) -- operand must be on the 'stack'
  1040. self:codearith(fs, "OP_CONCAT", e1, e2)
  1041. end
  1042. else
  1043. -- the following uses a table lookup in place of conditionals
  1044. local arith = self.arith_op[op]
  1045. if arith then
  1046. self:codearith(fs, arith, e1, e2)
  1047. else
  1048. local comp = self.comp_op[op]
  1049. if comp then
  1050. self:codecomp(fs, comp, self.comp_cond[op], e1, e2)
  1051. else
  1052. assert(0)
  1053. end
  1054. end--if arith
  1055. end--if op
  1056. end
  1057.  
  1058. ------------------------------------------------------------------------
  1059. -- adjusts debug information for last instruction written, in order to
  1060. -- change the line where item comes into existence
  1061. -- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat()
  1062. ------------------------------------------------------------------------
  1063. function luaK:fixline(fs, line)
  1064. fs.f.lineinfo[fs.pc - 1] = line
  1065. end
  1066.  
  1067. ------------------------------------------------------------------------
  1068. -- general function to write an instruction into the instruction buffer,
  1069. -- sets debug information too
  1070. -- * used in luaK:codeABC(), luaK:codeABx()
  1071. -- * called directly by (lparser) luaY:whilestat()
  1072. ------------------------------------------------------------------------
  1073. function luaK:code(fs, i, line)
  1074. local f = fs.f
  1075. self:dischargejpc(fs) -- 'pc' will change
  1076. -- put new instruction in code array
  1077. luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil,
  1078. luaY.MAX_INT, "code size overflow")
  1079. f.code[fs.pc] = i
  1080. -- save corresponding line information
  1081. luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil,
  1082. luaY.MAX_INT, "code size overflow")
  1083. f.lineinfo[fs.pc] = line
  1084. local pc = fs.pc
  1085. fs.pc = fs.pc + 1
  1086. return pc
  1087. end
  1088.  
  1089. ------------------------------------------------------------------------
  1090. -- writes an instruction of type ABC
  1091. -- * calls luaK:code()
  1092. ------------------------------------------------------------------------
  1093. function luaK:codeABC(fs, o, a, b, c)
  1094. assert(luaP:getOpMode(o) == luaP.OpMode.iABC)
  1095. assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0)
  1096. assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0)
  1097. return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline)
  1098. end
  1099.  
  1100. ------------------------------------------------------------------------
  1101. -- writes an instruction of type ABx
  1102. -- * calls luaK:code(), called by luaK:codeAsBx()
  1103. ------------------------------------------------------------------------
  1104. function luaK:codeABx(fs, o, a, bc)
  1105. assert(luaP:getOpMode(o) == luaP.OpMode.iABx or
  1106. luaP:getOpMode(o) == luaP.OpMode.iAsBx)
  1107. assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN)
  1108. return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline)
  1109. end
  1110.  
  1111. ------------------------------------------------------------------------
  1112. --
  1113. -- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield()
  1114. ------------------------------------------------------------------------
  1115. function luaK:setlist(fs, base, nelems, tostore)
  1116. local c = math.floor((nelems - 1)/luaP.LFIELDS_PER_FLUSH) + 1
  1117. local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore
  1118. assert(tostore ~= 0)
  1119. if c <= luaP.MAXARG_C then
  1120. self:codeABC(fs, "OP_SETLIST", base, b, c)
  1121. else
  1122. self:codeABC(fs, "OP_SETLIST", base, b, 0)
  1123. self:code(fs, luaP:CREATE_Inst(c), fs.ls.lastline)
  1124. end
  1125. fs.freereg = base + 1 -- free registers with list values
  1126. end
  1127.  
  1128. return function(a) luaY = a return luaK end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement